Old 11-09-2019, 10:12 AM   #601
woodslanding
Human being with feelings
 
woodslanding's Avatar
 
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
Default

Quote:
Originally Posted by Lokasenna View Post
The previous versions were all double quotes as well. As for why:
- IMO doubles make slightly more sense since single quotes/apostrophes are more likely to appear in a UI's text.
I think this is the best argument... sold.

Looks like there may be enough image support here for me to port my IControl class over to V3 without having to edit the base classes (which I did before). I'll submit it for your inspection when I get something working.
__________________
eric moon
Very Stable Genius
https://gogolab.com/
woodslanding is offline   Reply With Quote
Old 11-09-2019, 11:45 PM   #602
woodslanding
Human being with feelings
 
woodslanding's Avatar
 
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
Default

I'm trying to figure out what the (...) syntax does in LUA. I'm searching on google, and it doesn't seem to be 'searchable'! Google turns nothing up for it.

Do you know where I might be able to read up on it?
__________________
eric moon
Very Stable Genius
https://gogolab.com/
woodslanding is offline   Reply With Quote
Old 11-10-2019, 12:24 AM   #603
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
Default

They're called vararg functions: https://www.lua.org/manual/5.3/manual.html#3.4.11. The vararg expression ... (three dots) stores all extra parameters that were given to the function (it's not a table, more like functions with multiple return values).

Last edited by cfillion; 11-10-2019 at 12:46 AM.
cfillion is offline   Reply With Quote
Old 11-10-2019, 10:18 PM   #604
woodslanding
Human being with feelings
 
woodslanding's Avatar
 
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
Default

Quote:
Originally Posted by cfillion View Post
They're called vararg functions: https://www.lua.org/manual/5.3/manual.html#3.4.11. The vararg expression ... (three dots) stores all extra parameters that were given to the function (it's not a table, more like functions with multiple return values).
Thanks! A lot of good information there about how arguments work.

I'm going to have to get my head around passing functions around. It's all new to me and makes my head spin a bit....

As an example, in 'working with images' I find:

Code:
if self:containsPoint(state.mouse.x, state.mouse.y) then

		self.func(table.unpack(self.params))
self.params here refers to func's self, is that right? Am I right in thinking that func as an argument to the control should be the function we want it to execute when the button is pressed?

I'm trying to imagine what syntax I would use to have the func parameter call an action that required the value of self.state as an argument... I've figured other ways to do that without func, (basically overriding the control's mouse methods with direct calls) but it seems like I'm missing the point. There is an easier way, correct?

Okay, searched in Knob.lua, and it looks like the func argument is not being used in this way there, so maybe I was mistaken. Is what I'm talking about above possible? or desirable?
__________________
eric moon
Very Stable Genius
https://gogolab.com/

Last edited by woodslanding; 11-10-2019 at 10:55 PM.
woodslanding is offline   Reply With Quote
Old 11-11-2019, 07:35 AM   #605
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Quote:
Originally Posted by woodslanding View Post
Thanks! A lot of good information there about how arguments work.

I'm going to have to get my head around passing functions around. It's all new to me and makes my head spin a bit....

As an example, in 'working with images' I find:

Code:
if self:containsPoint(state.mouse.x, state.mouse.y) then

		self.func(table.unpack(self.params))
self.params here refers to func's self, is that right? Am I right in thinking that func as an argument to the control should be the function we want it to execute when the button is pressed?
self is just an argument; in this case self is the IButton. If you're used to something like Javascript's this, self isn't passed around the same way.

Quote:
I'm trying to imagine what syntax I would use to have the func parameter call an action that required the value of self.state as an argument... I've figured other ways to do that without func, (basically overriding the control's mouse methods with direct calls) but it seems like I'm missing the point. There is an easier way, correct?
I've just pushed an update for you. . User functions for Button, Menubar, and the IButton example in the image script all receive self as their first argument. i.e. when creating them you would use:
Code:
func = function(self, a, b, c) Msg(self.name, a, b, c) end,
params = {"a", "b", "c"}
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 11-11-2019, 10:31 AM   #606
woodslanding
Human being with feelings
 
woodslanding's Avatar
 
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
Default

oh, sweet, thanks!
__________________
eric moon
Very Stable Genius
https://gogolab.com/
woodslanding is offline   Reply With Quote
Old 11-13-2019, 10:36 AM   #607
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 517
Default

Is it possible to set the inc paramter of the Slider class to something smaller than 1? I´d like to keep the range at 1 top at the beginning and inc something like 0,01, cause then i wouldnt need to do any math, should the user change the range of the fader.
reapero is offline   Reply With Quote
Old 11-13-2019, 10:38 AM   #608
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Quote:
Originally Posted by reapero View Post
Is it possible to set the inc paramter of the Slider class to something smaller than 1? I´d like to keep the range at 1 top at the beginning and inc something like 0,01, cause then i wouldnt need to do any math, should the user change the range of the fader.
Yup. One of the sliders in the General Demonstration example has increments of 0.25:
Code:
GUI.New("my_sldr", 	"Slider",		4, 128, 256, 128, "Slider", 0, 10, 20, 0.25, "v")
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 11-14-2019, 02:00 AM   #609
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 517
Default

So how come this doesnt work? I kept the formatting that your GUI builder puked:

Code:
GUI.New("Offset", "Slider", {
    z = 11,
    x = 64.0,
    y = 340,
    w = 96,
    caption = "Offset",
    min = offset_min,
    max = offset_max,
    defaults = {0,0},
    inc = 0.1,
    dir = "h",
    font_a = 2,
    font_b = 4,
    col_txt = "txt",
    col_fill = "elm_fill",
    bg = "wnd_bg",
    show_handles = true,
    show_values = true,
    cap_x = 0,
    cap_y = 0
    
})
Offset_min is 0 and offset_max is 1. The slider goes straight from 0 to 1, no steps allowed.

Last edited by reapero; 11-14-2019 at 03:37 AM.
reapero is offline   Reply With Quote
Old 11-14-2019, 07:17 AM   #610
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

My bad; it wasn't picking up the inc parameter for elements created as a table. Pushing a fix up now.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 11-14-2019, 01:05 PM   #611
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 517
Default

Thanks Loka. Working nicely now!
reapero is offline   Reply With Quote
Old 11-16-2019, 09:11 AM   #612
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 517
Default

Ok, please bear with me. This is more like a SetExtState quetion but related to the usage of this GUI library somehow.

So i have set up this script with 10 sliders, most of them are double (table output). I want to create presets for the script, so i´d like to use ExtStates to store these settings. Now looking at the API:

Code:
reaper.SetExtState( section, key, value, persist )
Correct me if i am wrong but for this case this will turn out to be something like this:

reaper.SetExtState( "MY_PLUGIN", "PRESET_NUMBER_X", data, true)

That means i have to store A LOT of values in the "data" string. A lot like meaning every fader has its own max and min, its couple values if its a table, etc. That will probably become an ugly long string like "0,10,01,07,0,100,0,0,2,20,0...." separated by comma or space.

Is that the way to go here? Its going to be very hard for me to navigate thru this string to locate problems, cause i´ll probably forget what is what. I can create a function that separates this values and sends them into the right variables but even so, i wonder if i am just making things more complicated than they should.

thank you
reapero is offline   Reply With Quote
Old 11-16-2019, 02:25 PM   #613
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Quote:
Originally Posted by reapero View Post
i wonder if i am just making things more complicated than they should.
Putting a bunch of values into one string and splitting them back out again is actually the most common way to do this.

If your presets are flat - that is, they don't have any nested tables - it's really easy:

Code:
-- Make sure the characters you use aren't in the data, or you'll have to add
-- some logic to hande them
local keyValueSeparator = "="
local fieldSeparator = "&"

local function hashToExtString(hash)
  local out = {}
  for k, v in pairs(hash) do
    out[#out + 1] = k .. keyValueSeparator .. v
  end
  return out.concat(fieldSeparator)
end

local function hashFromExtString(ext)
  local out = {}
  for pair in ext:gmatch("[^" .. fieldSeparator .. "]+") do
    local k, v = pair:match("(.+)=(.+)")

    if tonumber(v) then
      v = tonumber(v)
    elseif v == "true" then
      v = true
    elseif v == "false" then
      v = false
    end

    out[k] = v
  end

  return out
end


--------------------
-- To save:

local presets = {
  {
    name = "apple",
    min = 5,
    max = 10,
  },
  {
    name = "banana",
    min = 0,
    max = 3,
  },
  {
    name = "cherry",
    min = 2,
    max = 9,
  }
}

for i, preset in pairs(presets) do
  local extString = hashToExtString(preset)
  reaper.SetExtState("MY_PLUGIN", "PRESET_NUMBER_" .. i, extString, true)
end

--------------------
-- To load:

local presets = {}

for i = 1, NUMBER_OF_PRESETS do
  local extString = reaper.GetExtState("MY_PLUGIN", "PRESET_NUMBER_"..i)

  presets[i] = hashFromExtString(extString)
end
(Note: Don't have a chance to test this)

If you do have nested tables, it's a bit more work. Radial Menu stores its settings in a text file, and I found a function that writes all of the table contents as Lua code: https://github.com/ReaTeam/ReaScript...Menu.lua#L5000 . Loading them again is just a matter of reading in the file and telling Lua to execute it.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 11-23-2019, 08:29 AM   #614
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Small update for v2:

- Fix: Checklists with only a single item couldn't be set to false via GUI.Val("MyChecklist", false)

- Added documentation about Checklists' alternate behaviour with only one element

- Removed the HTML documentation from the Developer Tools package; I don't have the script that generates it from the wiki installed, and it's just one more thing I have to remember to do any time I want to update the docs.

The project wiki is now the sole source of documentation.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 11-29-2019, 08:24 AM   #615
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 517
Default

I am trying to populate a menubox with presets that are actually keys on a given section of a the exts-state.ini file. So the latest options of the opts parameter need to be given programtically.

After getting the keynames from Extsate i end up with a string like this:

Code:
preset_list = '"preset1","preset2","preset3"'

GUI.New("Preset_menubox", "Menubox", {
    z = 11,
    x = 500,
    y = 128,
    w = 128,
    h = 20,
    caption = "",
    optarray = {"PRESETS...","Save","Delete",">Load", preset_list },

This doesnt create 3 options at the end but just a long one with all the quotes. I guess this was a very dirty approach...

Is there anything i can do?
reapero is offline   Reply With Quote
Old 11-29-2019, 09:23 AM   #616
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Try this:
Code:
optarray = table.pack("PRESETS...","Save","Delete",">Load", table.unpack(preset_list)),
table.unpack dumps the contents of a table out as multiple return values, and table.pack takes all of its arguments and puts them into a new table.

By unpacking a table in a function call, all of the table elements are passed as separate function arguments.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 11-29-2019, 10:37 AM   #617
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 517
Default

Nice! Thanks

EDIT: Allright now i need to rebuid the menubox during the main loop, so that it reflects the newly created presets. I tried with the :redraw method but the GUI doesn't update.

Can this be done? Cheers

Last edited by reapero; 11-29-2019 at 11:01 AM.
reapero is offline   Reply With Quote
Old 11-29-2019, 02:39 PM   #618
babag
Human being with feelings
 
Join Date: Nov 2009
Posts: 2,227
Default

Quote:
Originally Posted by Lokasenna View Post
Have a look at the Menubar class - it has to do the same thing for drawing the green hover indicator.

onmouseover turns the indicator on: https://github.com/jalovatt/Lokasenn...nubar.lua#L275
onupdate checks if it should be turned off: https://github.com/jalovatt/Lokasenn...nubar.lua#L232
i just tried copying these two functions into my toolbar code, just above the local 'function btn_click(command)' line, and loading the menubar class. the toolbar does run but nothing happens on hovering over the various buttons. i'm guessing something needs to be added into the functions to tell them to change color? not sure how or where to do that.

thanks,
babag

Last edited by babag; 11-29-2019 at 02:48 PM.
babag is offline   Reply With Quote
Old 11-29-2019, 03:53 PM   #619
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Post the whole script (or put it on Dropbox and post a link)?
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 11-29-2019, 03:56 PM   #620
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Quote:
Originally Posted by reapero View Post
Nice! Thanks

EDIT: Allright now i need to rebuid the menubox during the main loop, so that it reflects the newly created presets. I tried with the :redraw method but the GUI doesn't update.

Can this be done? Cheers
Can't test right now, but I believe this should work:
Code:
GUI.elms.myMenubox.optarray = aNewArray
GUI.elms.myMenubox:redraw()
No?
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 11-29-2019, 07:23 PM   #621
D Rocks
Human being with feelings
 
Join Date: Dec 2017
Location: Quebec, Canada
Posts: 550
Default

I'd warmly welcome ReaPlugs to look like this!
__________________
Alex | www.drocksrecords.com | Thanks for REAPER
D Rocks is offline   Reply With Quote
Old 11-30-2019, 11:06 AM   #622
babag
Human being with feelings
 
Join Date: Nov 2009
Posts: 2,227
Default

thanks, lokasenna. the code below throws an error at line 237:

Code:
-- NoIndex: true

-- Makes an 8 x 8 grid of buttons user can put actions into.
-- Grid can be modified by editing User Options section to get the desired grid size.
-- Script was made to solve problem of Reaper floating toolbar rearranging buttons if window was resized by accident or otherwise.

-- The Core library must be loaded prior to anything else

local lib_path = reaper.GetExtState("Lokasenna_GUI", "lib_path_v2")
if not lib_path or lib_path == "" then
    reaper.MB("Couldn't load the Lokasenna_GUI library. Please run 'Script: Set Lokasenna_GUI v2 library path.lua' in your Action List.", "Whoops!", 0)
    return
end
loadfile(lib_path .. "Core.lua")()


GUI.req("Classes/Class - Button.lua")()
GUI.req("Classes/Class - Menubar.lua")()


-- If any of the requested libraries weren't found, abort the script.
if missing_lib then return 0 end


------------------------------------
-------- USER OPTIONS --------------
------------------------------------

local button_width      = 58    -- Set your button width  here
local button_height     = 28    -- Set your button height here
local buttons_per_row   = 8     -- Set how many buttons you want in each row here 
local button_h_spacer   = 3     -- Set how much horizontal space between buttons here
local button_v_spacer   = 2     -- Set how much vertical   space between buttons here


------------------------------------
-------- Functions  ----------------
------------------------------------

function GUI.Menubar:onmouseover()

    local opt = self.mousemnu

    local x = GUI.mouse.x - self.x

    if  self.mousemnu_x and x > self:measuretitles(nil, true) then

        self.mousemnu = nil
        self.mousemnu_x = nil
        self:redraw()

        return

    end


    -- Iterate through the titles by overall width until we
    -- find which one the mouse is in.
    for i = 1, #self.menus do

        if x <= self:measuretitles(i, true) then

            self.mousemnu = i
            self.mousemnu_x = self:measuretitles(i - 1, true)

            if self.mousemnu ~= opt then self:redraw() end

            return
        end

    end

end

function GUI.Menubar:onupdate()

    if self.mousemnu and not GUI.IsInside(self, GUI.mouse.x, GUI.mouse.y) then
        self.mousemnu = nil
        self.mousemnu_x = nil
        self:redraw()

        -- Skip the rest of the update loop for this elm
        return true
    end

end

local function btn_click(command)
	
	-- Be nice, give the user an Undo point
	reaper.Undo_BeginBlock()
	
    reaper.Main_OnCommand(reaper.NamedCommandLookup(command), 0)
    
	reaper.Undo_EndBlock("Toolbar Grid Template", 0)	
    
    -- Exit the script on the next update
	GUI.quit = false
	
end


------------------------------------
-------- GUI Elements --------------
------------------------------------

local elms = {}

-- Define your buttons below.

-- Copy, delete, or comment out label/command lines below to get the number of buttons you want.
        
-- Label field is for text that will be displayed on the the button.
-- Example: label = "PLAY\n130%",
-- Note that the \n causes a line break and will display the text on two lines.

-- Command field is for the command ID from the actions list.
-- Example 1: command = 65535
-- Example 2: command = "_eed3041ab48a593fcd3909218c058b46"
-- Note that example 1 has no quotes as it is a native Reaper action.
-- Note that example 2 has quotes as it is a custom action.
-- Note that command = 65535 can be used as a spacer. It is a "no-op" action.
-- Text can still be displayed even if the button is a "no-op" action.

local toolbar_buttons = {
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
}


------------------------------------
-------- Window settings -----------
------------------------------------

for k in ipairs(toolbar_buttons) do

    total_buttons = k
    
end    
    
local button_rows = (total_buttons / buttons_per_row)
local gui_w       = (button_width * buttons_per_row) + ((buttons_per_row - 1) * button_h_spacer)
local gui_h       = (button_height * button_rows) + ((button_rows - 1) * button_v_spacer)

GUI.name = "TOOLBAR GRID TEMPLATE"
--GUI.x, GUI.y, GUI.w, GUI.h = 0, 0, 972, 240
GUI.x, GUI.y, GUI.w, GUI.h = 0, 0, gui_w, gui_h
--GUI.x, GUI.y, GUI.w, GUI.h = 0, 0, gui_w, 208
GUI.anchor, GUI.corner = "mouse", "C"


------------------------------------
-------- GUI Elements cont. --------
------------------------------------

local buttons_count     = -1    -- Leave this one alone or screwy things will happen

for k, v in ipairs(toolbar_buttons) do
  if row_buttons   == (buttons_per_row - 1) then    -- Set conditions for switching to a new row
      row_buttons   = 0
  else
      buttons_count = (buttons_count + 1)
  end

  elms["button_"..k] = {
    type = "Button",
    col_fill = {.2,.2,.2},
    z = (#toolbar_buttons - k) + 1,
    x = ((k - 1) % buttons_per_row) * (button_width + button_h_spacer),
    y = math.floor((k - 1) / buttons_per_row) *  (button_height + button_v_spacer),
    w = button_width,
    h = button_height,
    caption = v.label,
    func = GUI.Menubar.onmouseover,
    func = GUI.Menubar:onupdate(col_fill = {.2,.8,.2}),
    func = btn_click,
    params = {v.command},       -- Send command parameter to the btn_click function so that it will accept a variable.
    tooltip = "I'm a button"
  }

end

GUI.CreateElms(elms)


GUI.Init()
GUI.Main()
all i've done is to add the two menubar functions in the 'functions' section near the top and then to add calls for them in the gui elements section near the end, the second with a color option. that's the line that throws the error.

edit:
oh, yeah, at the beginning added the menubar class.

thanks for looking at this,
babag
babag is offline   Reply With Quote
Old 11-30-2019, 03:42 PM   #623
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

- You can't use the Menubar code as-is because it's specifically written for the Menubar class - it references other properties and methods that the Button class won't have, and does things you don't need a Button to do.

- It's throwing an error because you can't pass a statement (col_fill = {.2,.8,.2}) as a function argument.

- You can't have more than one func = ___ - Lua will just overwrite the previous ones.

- func is also specifically for handling Button clicks; you have to specifically override the button's other methods.

This should do the trick. I've added a table, ToolbarButton, with the replacement button methods, and then assigned them to each button as it gets created.

Code:
-- NoIndex: true

-- Makes an 8 x 8 grid of buttons user can put actions into.
-- Grid can be modified by editing User Options section to get the desired grid size.
-- Script was made to solve problem of Reaper floating toolbar rearranging buttons if window was resized by accident or otherwise.

-- The Core library must be loaded prior to anything else

local lib_path = reaper.GetExtState("Lokasenna_GUI", "lib_path_v2")
if not lib_path or lib_path == "" then
    reaper.MB("Couldn't load the Lokasenna_GUI library. Please run 'Script: Set Lokasenna_GUI v2 library path.lua' in your Action List.", "Whoops!", 0)
    return
end
loadfile(lib_path .. "Core.lua")()

GUI.req("Classes/Class - Button.lua")()

-- If any of the requested libraries weren't found, abort the script.
if missing_lib then return 0 end


------------------------------------
-------- USER OPTIONS --------------
------------------------------------

local button_width      = 58    -- Set your button width  here
local button_height     = 28    -- Set your button height here
local buttons_per_row   = 8     -- Set how many buttons you want in each row here
local button_h_spacer   = 3     -- Set how much horizontal space between buttons here
local button_v_spacer   = 2     -- Set how much vertical   space between buttons here


------------------------------------
-------- Functions  ----------------
------------------------------------


local function btn_click(command)

	-- Be nice, give the user an Undo point
	reaper.Undo_BeginBlock()

    reaper.Main_OnCommand(reaper.NamedCommandLookup(command), 0)

	reaper.Undo_EndBlock("Toolbar Grid Template", 0)

    -- Exit the script on the next update
	GUI.quit = false

end


------------------------------------
-------- GUI Elements --------------
------------------------------------

local elms = {}

-- Define your buttons below.

-- Copy, delete, or comment out label/command lines below to get the number of buttons you want.

-- Label field is for text that will be displayed on the the button.
-- Example: label = "PLAY\n130%",
-- Note that the \n causes a line break and will display the text on two lines.

-- Command field is for the command ID from the actions list.
-- Example 1: command = 65535
-- Example 2: command = "_eed3041ab48a593fcd3909218c058b46"
-- Note that example 1 has no quotes as it is a native Reaper action.
-- Note that example 2 has quotes as it is a custom action.
-- Note that command = 65535 can be used as a spacer. It is a "no-op" action.
-- Text can still be displayed even if the button is a "no-op" action.

local toolbar_buttons = {
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
  { label = "",                   command = 65535 },
}


------------------------------------
-------- Window settings -----------
------------------------------------

for k in ipairs(toolbar_buttons) do

    total_buttons = k

end

local button_rows = (total_buttons / buttons_per_row)
local gui_w       = (button_width * buttons_per_row) + ((buttons_per_row - 1) * button_h_spacer)
local gui_h       = (button_height * button_rows) + ((button_rows - 1) * button_v_spacer)

GUI.name = "TOOLBAR GRID TEMPLATE"
--GUI.x, GUI.y, GUI.w, GUI.h = 0, 0, 972, 240
GUI.x, GUI.y, GUI.w, GUI.h = 0, 0, gui_w, gui_h
--GUI.x, GUI.y, GUI.w, GUI.h = 0, 0, gui_w, 208
GUI.anchor, GUI.corner = "mouse", "C"


------------------------------------
-------- GUI Elements cont. --------
------------------------------------


local ToolbarButton = {}

function ToolbarButton:onupdate()
  if self.hovered and not GUI.IsInside(self, GUI.mouse.x, GUI.mouse.y) then
    self.hovered = false
    self:redraw()

    -- Skip the rest of the update loop for this elm
    return true
  end
end

function ToolbarButton:onmouseover()
  if not self.hovered then
    self.hovered = true
    self:redraw()
  end
end

function ToolbarButton:draw()
  GUI.Button.draw(self)

  if self.hovered then
    GUI.color({1, 1, 1, 0.1})
    gfx.rect(self.x + 1 + 2 * self.state, self.y + 1 + 2 * self.state, self.w - 2, self.h - 2)
    gfx.a = 1
  end
end


local buttons_count     = -1    -- Leave this one alone or screwy things will happen

for k, v in ipairs(toolbar_buttons) do
  if row_buttons   == (buttons_per_row - 1) then    -- Set conditions for switching to a new row
      row_buttons   = 0
  else
      buttons_count = (buttons_count + 1)
  end

  elms["button_"..k] = {
    type = "Button",
    col_fill = {.2,.2,.2},
    z = (#toolbar_buttons - k) + 1,
    x = ((k - 1) % buttons_per_row) * (button_width + button_h_spacer),
    y = math.floor((k - 1) / buttons_per_row) *  (button_height + button_v_spacer),
    w = button_width,
    h = button_height,
    caption = v.label,
    func = btn_click,
    params = {v.command},       -- Send command parameter to the btn_click function so that it will accept a variable.
    tooltip = "I'm a button",
    onupdate = ToolbarButton.onupdate,
    onmouseover = ToolbarButton.onmouseover,
    draw = ToolbarButton.draw,
  }

end

GUI.CreateElms(elms)


GUI.Init()
GUI.Main()
This is one of the many things that will be easier to do in v3 - each event can have a before___ or after___ function attached to it rather than having to override the event method itself.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 11-30-2019, 04:03 PM   #624
babag
Human being with feelings
 
Join Date: Nov 2009
Posts: 2,227
Default

hey, thanks! i'd have never figured that out. :-P

looks like in the 'function ToolbarButton:draw()' there is a line:
Code:
GUI.color({1, 1, 1, 0.1})
that seems to control the mouseover brightness. i tried changing .1 to .5 and it gets much lighter. is there a way to apply color, maybe something like giving rgb values in parentheses or something? or does that asdd a whole new complication?

thanks again,
babag
babag is offline   Reply With Quote
Old 11-30-2019, 04:20 PM   #625
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Quote:
Originally Posted by babag View Post
hey, thanks! i'd have never figured that out. :-P

looks like in the 'function ToolbarButton:draw()' there is a line:
Code:
GUI.color({1, 1, 1, 0.1})
that seems to control the mouseover brightness. i tried changing .1 to .5 and it gets much lighter. is there a way to apply color, maybe something like giving rgb values in parentheses or something? or does that asdd a whole new complication?

thanks again,
babag
Those values are Red, Green, Blue, Alpha - just from 0 to 1 instead of 0 to 255.

Note that we do have to reset the alpha to 1 afterward (gfx.a = 1) or it will mess up drawing subsequent buttons.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 11-30-2019, 04:30 PM   #626
babag
Human being with feelings
 
Join Date: Nov 2009
Posts: 2,227
Default

cool! thanks!
babag is offline   Reply With Quote
Old 12-02-2019, 09:01 AM   #627
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 517
Default

Quote:
Originally Posted by Lokasenna View Post
Can't test right now, but I believe this should work:
Code:
GUI.elms.myMenubox.optarray = aNewArray
GUI.elms.myMenubox:redraw()
No?
YES! Thx
reapero is offline   Reply With Quote
Old 12-09-2019, 08:36 AM   #628
deeb
Human being with feelings
 
deeb's Avatar
 
Join Date: Feb 2017
Posts: 4,812
Default

Lokasenna! any idea when V3 will be released?
deeb is offline   Reply With Quote
Old 12-09-2019, 09:14 AM   #629
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Quote:
Originally Posted by deeb View Post
Lokasenna! any idea when V3 will be released?
When the items on my to-do list are either done or I decide they aren't important: https://github.com/jalovatt/scythe/i...223.0+Alpha%22

Documentation is the big one, but I'm struggling to stay motivated on it. I've got a system set up to automatically generate documentation (Preview here) for the new modules but I can't come up with an effective way to do the same for the element classes.

Between that, and Christmas, and Advent of Code... not sure. Maybe early January?
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 12-09-2019, 09:29 AM   #630
deeb
Human being with feelings
 
deeb's Avatar
 
Join Date: Feb 2017
Posts: 4,812
Default

Quote:
Originally Posted by Lokasenna View Post
When the items on my to-do list are either done or I decide they aren't important: https://github.com/jalovatt/scythe/i...223.0+Alpha%22

Documentation is the big one, but I'm struggling to stay motivated on it. I've got a system set up to automatically generate documentation (Preview here) for the new modules but I can't come up with an effective way to do the same for the element classes.

Between that, and Christmas, and Advent of Code... not sure. Maybe early January?
so it will be named "scythe"?

"but I'm struggling to stay motivated on it"
UP UP but you always first !

"but I can't come up with an effective way to do the same for the element classes."

Maybe mesopotine or someone else could give an insight?


I think i will start doing a new thing on V2.. and eventually port to v3 later.

Not wanting to push or anything at all, but i wonder if you plan to Plan more then 1 column for ListView?
example:
Title | Author | Age | Action | Slider | Button | ^ScrollBar^

Last edited by deeb; 12-09-2019 at 09:46 AM.
deeb is offline   Reply With Quote
Old 12-09-2019, 09:53 AM   #631
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Quote:
Originally Posted by deeb View Post
so it will be named "scythe"?
Yup. With the additional non-GUI modules it includes I felt a name change was appropriate, and it's a good opportunity to make a Reaper pun.

Quote:
I think i will start doing a new thing on V2.. and eventually port to v3 later.
Fair enough. I would suggest using the table syntax for creating your elements though, since v3 only uses that. i.e.
Code:
GUI.New("thing", "Button", {
  x = 1,
  y = 2,
  ...
})
Quote:
Not wanting to push or anything at all, but i wonder if you plan to Plan more then 1 column for ListView?
example:
Title | Author | Age | Action | Slider | Button | ^ScrollBar^
I hadn't thought of it, but I'll add that to my list of ideas.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 12-09-2019, 09:54 AM   #632
deeb
Human being with feelings
 
deeb's Avatar
 
Join Date: Feb 2017
Posts: 4,812
Default

Just experienced this and reminder to just say: Would be nice if "lokasenna" or "FrameworkName" would be in examples files names so that when searching in actions they gets easily found.

deeb is offline   Reply With Quote
Old 12-09-2019, 10:42 AM   #633
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

I'll think about it.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 12-11-2019, 04:35 PM   #634
woodslanding
Human being with feelings
 
woodslanding's Avatar
 
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
Default

your tiny tip of the 'searching for actions' iceberg....

We need a google search type algorithm for finding actions.... or the ability to assign them a bunch of search key words!
__________________
eric moon
Very Stable Genius
https://gogolab.com/
woodslanding is offline   Reply With Quote
Old 12-11-2019, 07:49 PM   #635
MusoBob
Human being with feelings
 
MusoBob's Avatar
 
Join Date: Sep 2014
Posts: 2,643
Default

Is there a way of scaling up the GUI and Radial Menu for HiDPI-Screens ?
__________________
ReaTrakStudio Chord Track for Reaper forum
www.reatrak.com
STASH Downloads https://stash.reaper.fm/u/ReaTrak
MusoBob is offline   Reply With Quote
Old 12-11-2019, 09:23 PM   #636
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Quote:
Originally Posted by MusoBob View Post
Is there a way of scaling up the GUI and Radial Menu for HiDPI-Screens ?
Not at the moment, but definitely worth looking into.

- It looks like I can use retval, name = reaper.ThemeLayout_GetLayout("mcp", -3) to get the DPI context (256 on a regular monitor, 512 on Retina).

- I... think?... it would just require intercepting any references to screen coordinates or pixel sizes and doubling them. Does that make sense? A lot of work and refactoring, but at least straightforward if that's the case.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 12-12-2019, 01:34 AM   #637
MusoBob
Human being with feelings
 
MusoBob's Avatar
 
Join Date: Sep 2014
Posts: 2,643
Default

Yes that's what I thought would be a way to do it.
I was going to try it with a slider to add/subtract from the size and co-ordinates but then you have to do a ondelete() and init() to refresh the elements ????
__________________
ReaTrakStudio Chord Track for Reaper forum
www.reatrak.com
STASH Downloads https://stash.reaper.fm/u/ReaTrak
MusoBob is offline   Reply With Quote
Old 12-12-2019, 07:28 AM   #638
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

For dynamic scaling, yeah. If you only needed to support either regular or HiDPI and nothing in between that becomes much easier because it can be a global wrapper for init that tells all of the elements to do it.

At any rate, v3 is probably a better place to test stuff like this since it's been refactored and tidied so much. If and when we figure out a good solution, I can look at back-porting it to v2.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 12-17-2019, 05:13 AM   #639
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 517
Default

Hi,

I have a bit of time to continue on my minimalistic approach building a preset system via menubox. I´ve run into this:



This happens when the user selects a preset (not init):



And the code here is:

Code:
function get_preset_list()
  number_of_presets, _ = ultraschall.CountIniFileExternalState_key("menubox_EXAMPLE",  reaper_extstate_ini_path)
   if number_of_presets > 0 then
       for k in pairs (preset_list) do
             preset_list[k] = nil
        end 
       for i= 1, number_of_presets do
          local preset_name = ultraschall.EnumerateIniFileExternalState_key("menubox_EXAMPLE", i, reaper_extstate_ini_path)
          table.insert(preset_list, preset_name)
       end
       return preset_list
    end
end

local function Main()

  if GUI.Val("Preset_menubox") > 6 then  --save preset
   selected_preset = GUI.Val("Preset_menubox")
   preset_list = get_preset_list()
  end

.....more ifs...
end

GUI.Init()
GUI.func = Main
GUI.freq = 0
GUI.Main()
I assume the loop is messing things up ("too many open files")? Is this related perhaps to the Ultraschall API?

Thanks!
reapero is offline   Reply With Quote
Old 12-17-2019, 07:22 AM   #640
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Yeah, it's the combination of loop + that Ultraschall function. The latter opens the file each time and runs through it to find the section number if you give. It does close the file afterward, but it looks like Lua isn't cleaning up quickly enough after itself.

I don't have time to test this right now, but try:
Code:
local function list_keys_in_ini_section (section, fn)
  local sections = {}

  local LOOKING = 1
  local WORKING = 2
  local DONE = 3
  local status = LOOKING

  for line in io.lines(fn) do
    if status == LOOKING and line:match("%["..section.."%]") then
      status = WORKING
    else if status == WORKING then
      if line:match(".+=.+") then
        sections.insert(line)
      else
        status = DONE
    end
  end

  return sections
end

function get_preset_list()
  local found_presets = list_keys_in_ini_section("menubox_EXAMPLE", reaper_extstate_ini_path)
  if #found_presets > 0 then
    preset_list = found_presets
  end
  -- number_of_presets, _ = ultraschall.CountIniFileExternalState_key("menubox_EXAMPLE",  reaper_extstate_ini_path)
  --  if number_of_presets > 0 then
  --      for k in pairs (preset_list) do
  --            preset_list[k] = nil
  --       end 
  --      for i = 1, number_of_presets do
  --         local preset_name = ultraschall.EnumerateIniFileExternalState_key("menubox_EXAMPLE", i, reaper_extstate_ini_path)
  --         table.insert(preset_list, preset_name)
  --      end
  --      return preset_list
  --   end
end
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 02:24 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.