|
|
|
06-04-2016, 02:02 PM
|
#1
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Lokasenna's GUI library for Lua v2
V3 update, February 2020 - v3 is now available on ReaPack! I'll make a separate thread for it when time allows, but in the meantime you can have a look at https://jalovatt.github.io/scythe
GUIs. We all need them, and they're a bit of a pain to make in ReaScript. Why not let someone else do the hard work so you can get back to actually making your script do something cool?
Installation:
ReaPack
- Install the Lokasenna's GUI library v2 for Lua package
- In Reaper's action list, run Set Lokasenna_GUI v2 library path.lua
Any scripts requiring this library should now be able to find it.
Manual
- Download the files here (including any subfolders), making sure to keep the same folder structure wherever you put them on your hard drive
- Find and run the install script, Set Lokasenna_GUI v2 library path.lua
Developers
A second package, Lokasenna's GUI library v2 for Lua (developer tools), provides example scripts, templates, and documentation.
Development:
All of my work is done at Lokasenna_GUI on Github. Everything there is to be considered unstable, and probably not suitable for release, but any new feature updates or class additions will show up there. Contributions, bug reports, etc are all welcome.
Enjoy!
Reasons why you should use this sexy beast include:
- It comes with a GUI builder! (Experimental, see the Developer Tools package)
- Very little coding required on your part. A simple GUI might need only a dozen lines of code compared to the hundreds (or thousands, for some of my scripts) you'd have to write if you did it yourself.
- Global font and color settings, so you can change the overall look to suit your fancy.
- Layer visibility management, so you can have multiple sets of controls or dialog boxes come and go as needed.
- Graphics use blitting whenever possible, keeping the CPU usage low without any worry on your part.
- Hooks to run your own functions as part of the GUI's updating loop. You could relabel the options around a knob if you wanted, or have a slider and knob match the selected track's volume/pan... etc.
- Built-in crash reporting, providing more detailed error messages than Reaper does by itself.
- Can be told to exit from your own code, and to run a function when it does. For instance, "save all the current settings, run this action, and quit".
- Numerous helper functions in addition to the GUI code, simplifying a number of things that might be annoying to code on your own every time.
- Modular design, allowing you to use as much, or as little, of my own code as you want. You can also write your own classes if you'd prefer.
Changelog:
July 8/18: The "Lokasenna GUI v2.x.x" watermark now reads its version from ReaPack so I don't have to remember to update it.
June 27/18: First stable release, available on ReaPack. It will only be updated directly with bug fixes - any feature updates and new classes will live on the project repository until I feel like they're safe to move over.
June 6/18: Added support for creating elements with keyed tables rather than a series of function arguments, and an example script demonstrating it.
June 2/18: New class - Window. A number of under-the-hood improvements and new Core functions. Better crash reporting, and handling of Reaper's "restricted permissions" mode.
May 10/18: Fixed some weirdness with how Knob and Slider return their values. This update changes the parameters for both classes and will break any scripts that use them. My apologies.
April 29/18: Added Menubar class.
April 25/18: Added a basic crash reporter, moved the project to my own repository on Github.
April 22/18: Went through all of the classes/scripts and did some major tidying, as well as breaking most of the longer functions into smaller chunks.
April 8/18: Added Listbox and TextEditor classes. There were also a number of bug fixes and efficiency improvements back in... February? I forget.
September 26/17: Bug fix - the Knob class was ignoring min/max values when drawing values around the knob.
August 19/17: Bug fixes related to macOS using decimal values for the mousewheel, and scrolling the mousewheel on a Menubox with no options in it.
July 31/17: A few bug fixes.
June 9/17: First proper release. Classes are modular, tons of new features, code is much more efficient.
June 13/16: Rewrote the library to be copy/paste-able rather than distributing the file separately.
Last edited by Lokasenna; 02-09-2020 at 03:25 PM.
|
|
|
06-04-2016, 06:13 PM
|
#2
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,876
|
Thanks for your hard work on this, I'm sure it could be useful to a lot of scripters !!
Cheers !
|
|
|
06-04-2016, 10:19 PM
|
#3
|
Human being with feelings
Join Date: Jun 2010
Location: Texas
Posts: 357
|
This is amazing, Lokasenna.
|
|
|
06-08-2016, 08:30 AM
|
#4
|
Human being with feelings
Join Date: Feb 2015
Posts: 753
|
This looks awesome!
|
|
|
06-08-2016, 12:56 PM
|
#5
|
Human being with feelings
Join Date: Feb 2009
Location: Dunedin, New Zealand
Posts: 205
|
Bravo! Amazing work and excellent reference scripts!
|
|
|
06-10-2016, 04:40 AM
|
#6
|
Human being with feelings
Join Date: Sep 2012
Location: Oz
Posts: 196
|
Great stuff! Thanks!!
|
|
|
06-11-2016, 05:16 AM
|
#7
|
Human being with feelings
Join Date: Mar 2013
Location: Moscow
Posts: 99
|
Looks great !
|
|
|
06-13-2016, 08:49 PM
|
#8
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Update to beta 2.
No feature changes, but I rewrote a couple of things so the library can now be copy/pasted into your script rather than distributing the file separately. See the comments at the beginning of the file for instructions.
|
|
|
06-14-2016, 06:21 PM
|
#9
|
Human being with feelings
Join Date: Mar 2013
Posts: 515
|
Just the licecap in the OP screams AWESOME!!!
Great stuff. Kudos!
__________________
"After silence, that which comes nearest to expressing the inexpressible is music", Aldous Huxley
|
|
|
06-15-2016, 11:14 AM
|
#10
|
Human being with feelings
Join Date: Aug 2012
Location: Finland
Posts: 2,668
|
I haven't tested this yet, but it's looking very good Thanks Lokasenna!
|
|
|
06-15-2016, 11:24 AM
|
#11
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,619
|
It's not possible to write JSFX plugins in Lua is it? I'd love to be able use this for FX as well, but I fear it's Eel or bust.
|
|
|
06-09-2017, 12:08 PM
|
#12
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Updated to version 1.0.
Lots of new features, new classes, bug fixes, efficiency improvements, 33% less sodium with the same great taste.
|
|
|
06-28-2017, 07:40 AM
|
#13
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,814
|
Quote:
Originally Posted by Lokasenna
Updated to version 1.0.
Lots of new features, new classes, bug fixes, efficiency improvements, 33% less sodium with the same great taste.
|
very nice ! thanks a lot! will check this today
|
|
|
06-29-2017, 06:18 AM
|
#14
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,814
|
hello Lokasenna! could you provide some example how to call a simple checkbox like the one you have in the original post, with "are you a cool guy?" , .. i tried yesterday but with no success.
Also, in the github examples, you are calling example: req("Classes//Class - Slider.lua") which in OSX gives an error and we have to change to: req("Classes\Class - Slider.lua"), so probably this could be sorted with a separator variable depending on the system.
Thank you
|
|
|
06-29-2017, 07:34 AM
|
#15
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,814
|
also! you could a provide a way to , without changing the knob class, to not show the 100 in the image:
the knob is like this:
GUI.New("my_knob", "Knob", 1, 230, 32, 80, "Attack", 0, 100, 101, 0,0)
you say in comments:
vals Boolean. Display value labels?
For knobs with a lot of steps, i.e. Pan from -100 to +100, set this
to false and use a label to read the value, update the Knob's caption
I have seted it to false, but marks still showing and the 100 is just the last mark.
Is there an example too?
Cheers!
|
|
|
07-01-2017, 02:16 AM
|
#16
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
1. A single-item checkbox just requires making one with no overall caption, and only one option in the list. There's also an option I seem to have missed when I was documenting everything, .frame, that lets you disable the border around the list:
Code:
GUI.New("my_chk", "Checklist", 1, 16, 16, 200, 32, "", "Are you a cool guy?")
GUI.elms.my_chk.frame = false
2. Good catch. As it happens, you can use GUI.file_sep here:
Code:
local sep = GUI.file_sep
req("Classes"..sep.."Class - Slider.lua")
If I get a chance I'll update the examples with that.
3. Working fine here:
Code:
GUI.New("my_knob", "Knob", 1, 230, 32, 80, "Attack", 0, 100, 101, 0,0)
GUI.elms.my_knob.vals = false
|
|
|
07-01-2017, 03:10 AM
|
#17
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Small update.
- Added the file separator check described above to all of the example files.
- Added a missing parameter to the Checklist documentation. .frame is a Boolean, defaults to True, and tells it whether or not to draw a frame around the list.
|
|
|
07-20-2017, 05:28 PM
|
#18
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,814
|
nice Lokasenna ! meanwhile i noticed that when adding values of 10 ~ or more for padding , the checkbox and also the radio has strange behaviour you click on D , C gets some times checked, Click on C checks D same times, and so on Can you check if you get the same?
In example:
GUI.New("chklist", "Checklist",1, 30 ,20 , 100, 150, "","A,B,C,D","v", 20 )
Last edited by deeb; 07-20-2017 at 05:50 PM.
|
|
|
07-21-2017, 06:37 AM
|
#19
|
Human being with feelings
Join Date: Dec 2016
Posts: 373
|
Pretty cool. I am going to utilize this.
If there a way to include this lib, like a lib/include? or does it need to be in the same file as the other lua code? (still learning LUA)
|
|
|
07-21-2017, 07:14 AM
|
#20
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,814
|
Quote:
Originally Posted by Flaneurette
Pretty cool. I am going to utilize this.
If there a way to include this lib, like a lib/include? or does it need to be in the same file as the other lua code? (still learning LUA)
|
in the GUI examples lokasenna did for us, he uses a custom function called "req". Probably you could check it.
|
|
|
07-21-2017, 08:48 AM
|
#21
|
Human being with feelings
Join Date: Dec 2016
Posts: 373
|
Quote:
Originally Posted by deeb
in the GUI examples lokasenna did for us, he uses a custom function called "req". Probably you could check it.
|
Got it! the Example - General demonstration.lua explains it.
|
|
|
07-21-2017, 10:05 AM
|
#22
|
Human being with feelings
Join Date: Dec 2016
Posts: 373
|
Lokasenna,
Is it possible to dump an (multidimensional) array/table inside a menu? would be cool. As I can see, it's only string right now.
Like:
Code:
GUI.New("my_mnu", "Menubox", 3, 256, 176, 64, 20, "Options:", MyArray)
Code:
MyArray = {
{'FOO', 5},
{'BAR', 2}
...etc
}
|
|
|
07-22-2017, 06:44 AM
|
#23
|
Human being with feelings
Join Date: Dec 2016
Posts: 373
|
Another thing that might be interesting. When filling a menubox with many items, it overflows:
But it does something strange too, it seems to repeat certain values at the bottom and grey them out:
|
|
|
07-22-2017, 02:16 PM
|
#24
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by deeb
nice Lokasenna ! meanwhile i noticed that when adding values of 10 ~ or more for padding , the checkbox and also the radio has strange behaviour you click on D , C gets some times checked, Click on C checks D same times, and so on Can you check if you get the same?
In example:
GUI.New("chklist", "Checklist",1, 30 ,20 , 100, 150, "","A,B,C,D","v", 20 )
|
I think the issue is that my check for "what option is the mouse over?" doesn't correct for padding at the top/bottom. Or something like that.
Will have a look.
|
|
|
07-22-2017, 02:22 PM
|
#25
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by Flaneurette
Lokasenna,
Is it possible to dump an (multidimensional) array/table inside a menu? would be cool. As I can see, it's only string right now.
|
It would much easier to do on your end than to build it into the GUI class, since I can't know what dimensions and indexing are being used for a user's table.
For the table listed above, you could do something like this (code might not be 100% correct, can't check it right now):
Code:
local function GetMenuItems()
local str = ""
for i = 1, #MyArray - 1 do
str = str..MyArray[i][1]..","
end
-- This avoids an extra , at the end of the string
str = str..MyArray[#MyArray][1]
return str
end
...
GUI.New("my_mnu", "Menubox", 3, 256, 176, 64, 20, "Options:", GetMenuItems())
|
|
|
07-22-2017, 02:27 PM
|
#26
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by Flaneurette
Another thing that might be interesting. When filling a menubox with many items, it overflows
|
There's no way (AFAIK) to restrict the menu's length or tell it to wrap to a second column - the menu itself is a function provided by Reaper. You should get little up/down arrows when it leaves the screen though.
Quote:
But it does something strange too, it seems to repeat certain values at the bottom and grey them out
|
Reaper's gfx.showmenu function uses specific prefixes for folders, graying out, etc, so that should only happen if a menu item starts with "#". See: https://www.extremraym.com/cloud/rea...a_gfx.showmenu
How are you generating the list? The Menubox class doesn't (well, shouldn't be) do anything with the list you give it aside from changing the commas to |s.
|
|
|
07-23-2017, 06:20 AM
|
#27
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,814
|
Quote:
Originally Posted by Lokasenna
I think the issue is that my check for "what option is the mouse over?" doesn't correct for padding at the top/bottom. Or something like that.
Will have a look.
|
Yep seems something like that: Mouse Over is not being affected by The padding. Thank you lokasenna
|
|
|
07-23-2017, 06:41 AM
|
#28
|
Human being with feelings
Join Date: Dec 2016
Posts: 373
|
Quote:
Originally Posted by Lokasenna
|
Hah! Yes, I use # for sharps... that's hilarious. As if sharps aren't used in music... what was he thinking! lol.
So... how were going to use sharps? will it take unicode? escaping it with another sharp doesn't work...
|
|
|
07-23-2017, 06:56 AM
|
#29
|
Human being with feelings
Join Date: Dec 2016
Posts: 373
|
Using the UTF-8 glyph seems to work: ♯
Or, a somewhat cleaner method:
|
|
|
07-23-2017, 09:35 AM
|
#30
|
Human being with feelings
Join Date: Dec 2016
Posts: 373
|
Also made a custom adjustment/preference in the Menubox.lua.
Code:
290 local x, y = self.x, self.y
291 gfx.x, gfx.y = self.x, self.y + 20
or
Code:
290 self.__index = self
291 gfx.x, gfx.y = self.x, self.y + 20
instead of:
Code:
290 gfx.x, gfx.y = GUI.mouse.x, GUI.mouse.y
This way the dropdown will fit tightly next, and under the menubox instead of floating around wherever I click.
|
|
|
07-23-2017, 03:10 PM
|
#31
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,814
|
Would like to make a request, probably would be nice if elements like:
Menubox,
Checklist,
Radio,
even knobs
accept a function as argument like button does for onclick, but in this case for onselect, so that some actions could be maded based on this information immediatlly.
Thanks!!
|
|
|
07-24-2017, 07:02 PM
|
#32
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
You can do that easily yourself by rewriting the appropriate method for whichever element you want. i.e:
Code:
--Load all the classes
GUI.New("mnu_mymenu", "Menubox", ...whatever the Menubox params are...)
function GUI.elms.mnu_mymenu:onmouseup()
-- Run the existing code for the menu
-- This could be after your extra code instead if you want
GUI.Menubox.onmouseup(self)
DoMyStuff(self.retval)
end
Or, if you need to do that with multiple elements, you can easily create a new class based on Menubox and rewrite the method for that:
Code:
-- Load all your libraries
GUI.MyMenuBox = GUI.Menubox
function GUI.MyMenuBox:onmouseup()
-- As above
end
See the example scripts for an, er, example of this in action. The code/formatting above might not be correct.
|
|
|
07-27-2017, 10:06 AM
|
#33
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,814
|
Quote:
Originally Posted by Lokasenna
You can do that easily yourself by rewriting the appropriate method for whichever element you want. i.e:
Code:
--Load all the classes
GUI.New("mnu_mymenu", "Menubox", ...whatever the Menubox params are...)
function GUI.elms.mnu_mymenu:onmouseup()
-- Run the existing code for the menu
-- This could be after your extra code instead if you want
GUI.Menubox.onmouseup(self)
DoMyStuff(self.retval)
end
Or, if you need to do that with multiple elements, you can easily create a new class based on Menubox and rewrite the method for that:
Code:
-- Load all your libraries
GUI.MyMenuBox = GUI.Menubox
function GUI.MyMenuBox:onmouseup()
-- As above
end
See the example scripts for an, er, example of this in action. The code/formatting above might not be correct.
|
Back to this! awesome
|
|
|
07-27-2017, 11:08 AM
|
#34
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,814
|
Imagine this:
GUI.New("menu" ,"Menubox", 1, 1, 1, 250, 30, "", "A,B" )
How can i make this menu be defaulted to B when loading without changing the "A,B" string?
Thanks man!
|
|
|
07-28-2017, 02:42 PM
|
#35
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
GUI.Val can be used for both reading and setting elements' values:
Code:
GUI.New("menu" ,"Menubox", 1, 1, 1, 250, 30, "", "A,B" )
GUI.Val("menu", 2)
|
|
|
07-29-2017, 08:34 AM
|
#36
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,814
|
Quote:
Originally Posted by deeb
nice Lokasenna ! meanwhile i noticed that when adding values of 10 ~ or more for padding , the checkbox and also the radio has strange behaviour you click on D , C gets some times checked, Click on C checks D same times, and so on Can you check if you get the same?
In example:
GUI.New("chklist", "Checklist",1, 30 ,20 , 100, 150, "","A,B,C,D","v", 20 )
|
This is Whats is buggin me now . I'll try and see if i can fix ir later
|
|
|
07-29-2017, 08:36 AM
|
#37
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,814
|
Is it possible without changing tab classe Tô have tabs with multiple rows?
|
|
|
07-29-2017, 02:53 PM
|
#38
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by deeb
This is Whats is buggin me now . I'll try and see if i can fix ir later
|
That would be awesome; I'm a couple of weeks away from having any time to fiddle with it myself.
Both of them use the same logic - Checklist in nmouseup and Radio in nmousedown:
Code:
-- See which option it's on
local mouseopt = self.dir == "h" and (GUI.mouse.x - (self.x + 0.5*self.chk_w))
or (GUI.mouse.y - (self.y + self.cap_h + self.pad) )
mouseopt = mouseopt / ((self.chk_w + self.pad) * #self.optarray)
mouseopt = GUI.clamp( math.floor(mouseopt * #self.optarray) + 1 , 1, #self.optarray )
Edit: I can't actually reproduce it on my end. If the checklist's height is too small then the last couple of options spill outside the frame and aren't clickable, but it appears to be properly detecting the option I'm over.
Quote:
Originally Posted by deeb
Is it possible without changing tab classe Tô have tabs with multiple rows?
|
Not at the moment.
Last edited by Lokasenna; 07-29-2017 at 03:07 PM.
|
|
|
07-29-2017, 03:03 PM
|
#39
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,814
|
ok! thanks ! all good meanwhile
|
|
|
07-29-2017, 05:21 PM
|
#40
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,814
|
Quote:
Originally Posted by Lokasenna
You can do that easily yourself by rewriting the appropriate method for whichever element you want. i.e:
Code:
--Load all the classes
GUI.New("mnu_mymenu", "Menubox", ...whatever the Menubox params are...)
function GUI.elms.mnu_mymenu:onmouseup()
-- Run the existing code for the menu
-- This could be after your extra code instead if you want
GUI.Menubox.onmouseup(self)
DoMyStuff(self.retval)
end
Or, if you need to do that with multiple elements, you can easily create a new class based on Menubox and rewrite the method for that:
Code:
-- Load all your libraries
GUI.MyMenuBox = GUI.Menubox
function GUI.MyMenuBox:onmouseup()
-- As above
end
See the example scripts for an, er, example of this in action. The code/formatting above might not be correct.
|
Thanks for your last edit, i will go to that part next
some days ago i had to use this:
Code:
function GUI.elms.menu1:onmouseup()
(...)
GUI.Menubox.onmouseup(self)
end
and it worked.
but now i had the need to use this, to make the onmouse work for many elements:
Code:
function GUI.MyMenuBox:onmouseup()
GUI.Menubox.onmouseup(self)
end
and i have an error: "stack overflow" on the console. I still didnt find how to solve! would be nice!
Edit: meanwhile i changed function GUI.Checklist nmouseup()and seems better now
Code:
local mouseopt = self.dir == "h" and (GUI.mouse.x - (self.x + 0.5*self.chk_w))
or (GUI.mouse.y - (self.y + self.cap_h ))
altho i don't like much that between checkboxes that space is always "clickable". . In this case for the checkbox before.But it is what it is ! it's great anyway.thank you
Last edited by deeb; 07-29-2017 at 08:13 PM.
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 02:01 AM.
|