|
|
|
11-09-2019, 10:12 AM
|
#601
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
Quote:
Originally Posted by Lokasenna
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.
|
|
|
11-09-2019, 11:45 PM
|
#602
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
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?
|
|
|
11-10-2019, 12:24 AM
|
#603
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,967
|
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.
|
|
|
11-10-2019, 10:18 PM
|
#604
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
Quote:
Originally Posted by cfillion
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?
Last edited by woodslanding; 11-10-2019 at 10:55 PM.
|
|
|
11-11-2019, 07:35 AM
|
#605
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by woodslanding
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"}
|
|
|
11-11-2019, 10:31 AM
|
#606
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
oh, sweet, thanks!
|
|
|
11-13-2019, 10:36 AM
|
#607
|
Human being with feelings
Join Date: Aug 2011
Posts: 522
|
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.
|
|
|
11-13-2019, 10:38 AM
|
#608
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by reapero
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")
|
|
|
11-14-2019, 02:00 AM
|
#609
|
Human being with feelings
Join Date: Aug 2011
Posts: 522
|
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.
|
|
|
11-14-2019, 07:17 AM
|
#610
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
My bad; it wasn't picking up the inc parameter for elements created as a table. Pushing a fix up now.
|
|
|
11-14-2019, 01:05 PM
|
#611
|
Human being with feelings
Join Date: Aug 2011
Posts: 522
|
Thanks Loka. Working nicely now!
|
|
|
11-16-2019, 09:11 AM
|
#612
|
Human being with feelings
Join Date: Aug 2011
Posts: 522
|
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
|
|
|
11-16-2019, 02:25 PM
|
#613
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by reapero
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.
|
|
|
11-23-2019, 08:29 AM
|
#614
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
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.
|
|
|
11-29-2019, 08:24 AM
|
#615
|
Human being with feelings
Join Date: Aug 2011
Posts: 522
|
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?
|
|
|
11-29-2019, 09:23 AM
|
#616
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
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.
|
|
|
11-29-2019, 10:37 AM
|
#617
|
Human being with feelings
Join Date: Aug 2011
Posts: 522
|
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.
|
|
|
11-29-2019, 02:39 PM
|
#618
|
Human being with feelings
Join Date: Nov 2009
Posts: 2,232
|
Quote:
Originally Posted by Lokasenna
|
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.
|
|
|
11-29-2019, 03:53 PM
|
#619
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Post the whole script (or put it on Dropbox and post a link)?
|
|
|
11-29-2019, 03:56 PM
|
#620
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by reapero
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?
|
|
|
11-29-2019, 07:23 PM
|
#621
|
Human being with feelings
Join Date: Dec 2017
Location: Quebec, Canada
Posts: 550
|
I'd warmly welcome ReaPlugs to look like this!
|
|
|
11-30-2019, 11:06 AM
|
#622
|
Human being with feelings
Join Date: Nov 2009
Posts: 2,232
|
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
|
|
|
11-30-2019, 03:42 PM
|
#623
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
- 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.
|
|
|
11-30-2019, 04:03 PM
|
#624
|
Human being with feelings
Join Date: Nov 2009
Posts: 2,232
|
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
|
|
|
11-30-2019, 04:20 PM
|
#625
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by babag
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.
|
|
|
11-30-2019, 04:30 PM
|
#626
|
Human being with feelings
Join Date: Nov 2009
Posts: 2,232
|
cool! thanks!
|
|
|
12-02-2019, 09:01 AM
|
#627
|
Human being with feelings
Join Date: Aug 2011
Posts: 522
|
Quote:
Originally Posted by Lokasenna
Can't test right now, but I believe this should work:
Code:
GUI.elms.myMenubox.optarray = aNewArray
GUI.elms.myMenubox:redraw()
No?
|
YES! Thx
|
|
|
12-09-2019, 08:36 AM
|
#628
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,820
|
Lokasenna! any idea when V3 will be released?
|
|
|
12-09-2019, 09:14 AM
|
#629
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by deeb
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?
|
|
|
12-09-2019, 09:29 AM
|
#630
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,820
|
Quote:
Originally Posted by Lokasenna
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.
|
|
|
12-09-2019, 09:53 AM
|
#631
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by deeb
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.
|
|
|
12-09-2019, 09:54 AM
|
#632
|
Human being with feelings
Join Date: Feb 2017
Posts: 4,820
|
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.
|
|
|
12-09-2019, 10:42 AM
|
#633
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
I'll think about it.
|
|
|
12-11-2019, 04:35 PM
|
#634
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
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!
|
|
|
12-11-2019, 07:49 PM
|
#635
|
Human being with feelings
Join Date: Sep 2014
Posts: 2,643
|
Is there a way of scaling up the GUI and Radial Menu for HiDPI-Screens ?
|
|
|
12-11-2019, 09:23 PM
|
#636
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by MusoBob
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.
|
|
|
12-12-2019, 01:34 AM
|
#637
|
Human being with feelings
Join Date: Sep 2014
Posts: 2,643
|
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 ????
|
|
|
12-12-2019, 07:28 AM
|
#638
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
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.
|
|
|
12-17-2019, 05:13 AM
|
#639
|
Human being with feelings
Join Date: Aug 2011
Posts: 522
|
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!
|
|
|
12-17-2019, 07:22 AM
|
#640
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
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
|
|
|
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 07:17 PM.
|