Old 05-12-2019, 11:26 AM   #1
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 289
Default What's going on here? (Lokesanna's GUI)

I am trying to figure out why this... 'thing' for the lack of a better word, is happening.

Within the attached script there's an oddity happening whereby the labels on tabs 1 and 2 are being affected by the number of labels on tabs 3 and 4.

I split the original function up into two to help track down where this oddity is coming from, and I narrowed it down further to the length of the table for placing the labels in Tabs 3 and 4.
Code:
function AddSermonGUI(Tab_Index, c)
	local K = 8

	for i = 1, K do -- tablelength(SermonCaptions) do
		GUI.New(SermonCaptions[i], "Label",{z = 31, caption = SermonCaptions[i], x = SermonCaptionsX[i], y = 30, font = 2, color="txt", bg = "wnd_bg", shadow = false})
	end
A) If set K to 8, which is what it is supposed to be, the last three labels are missing on Tabs 1 and 2, but all of the labels appear correctly on Tabs 3 and 4.

B) If you change K to 7, the last label on Tabs 1 and 2 appear, but the two labels to the left of that one are missing, and last label on Tabs 3 and 4 is missing.

C) If you change K from 8 (the length of that specific table) to 6, all of the labels on Tabs 1 and 2 appear, but naturally the last two labels are missing from Tabs 3 and 4.

I'm almost positive that it's gotta be something simple, but what am I missing here??
Attached Files
File Type: lua Reaper DAW Interface - GUI Segment.lua (13.9 KB, 8 views)
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-12-2019, 02:32 PM   #2
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 5,883
Default

Because elements all live in one table (GUI.elms), they need to have unique names. You have the same captions for elements in multiple tabs, and you're using the captions as your element names, so the first one that gets created is being overwritten by the second.

The easiest solution would be to add "Tab1_", "Tab2_", etc. to the beginning of each element's name to avoid name collisions.
Lokasenna is offline   Reply With Quote
Old 05-13-2019, 03:51 PM   #3
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 289
Default

Quote:
Originally Posted by Lokasenna View Post
The easiest solution would be to add "Tab1_", "Tab2_", etc. to the beginning of each element's name to avoid name collisions.
You freakin' RAWK!! (Man, that was such a short and concise answer! And simple to fix too. Thank you!) I should've picked up on that name thing. Does that apply to every element? I mean, can textboxes and buttons share the same name or do they also have to be different?


New Question... now that I have this all separated from my main file, how do I go about referencing it as an external file? I'm not familiar with how Reaper / Lua treats library files. I thought it had something to do with {require}, but I guess I'm either wrong about that, or I'm doing it wrong.
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-13-2019, 03:58 PM   #4
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 5,883
Default

- All elements need to have unique names - they live in one table, and you can't have duplicate keys in a table. I usually prefix mine with the class to help me keep track of them, i.e. "btn_sermons_load", that sort of thing.

- require is necessary for a few specific things, but you should be able to use:
Code:
local my_other_module = dofile(GUI.script_path .. "my_other_module.lua")
...if it's in the same folder as your main script.
Lokasenna is offline   Reply With Quote
Old 05-13-2019, 05:00 PM   #5
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 289
Default

Quote:
Originally Posted by Lokasenna View Post
- All elements need to have unique names - they live in one table, and you can't have duplicate keys in a table. I usually prefix mine with the class to help me keep track of them, i.e. "btn_sermons_load", that sort of thing.
Thank you... good to know and now I have a better understanding on how the elements work.


Quote:
Originally Posted by Lokasenna View Post
- require is necessary for a few specific things, but you should be able to use:
Code:
local my_other_module = dofile(GUI.script_path .. "my_other_module.lua")
...if it's in the same folder as your main script.
I will look into this further once I resolve another challenge.


Another challeng... (See?? This is what happens when you have the very best answers.lol).

I'm trying to use this new found knowledge of tables to sort through the existing markers and re-label the buttons, but I'm missing something. Again, it's probably something really easy, but I haven't found my answer using Google or looking at your guide.

Code:
function ScanMarkers(MarkerNum, MarkerPos, MarkerCap)
	-- Scan Markers for updates / changes
		local mkr_idx = {} mkr_pos = {}  -- create mkr_idx and mkr_pos tables (arrays)
		local mkr_name = {} mkr_num = {}
		local num_mkrgns, num_markersOut, num_regionsOut = reaper.CountProjectMarkers(0)  -- count markers and regions in project
		-- MsgBox("num_mkrgns: " .. num_mkrgns .. "\nnum_markersOut: " .. num_markersOut .. "\nnum_regionsOut: " .. num_regionsOut)
		if num_markersOut then   -- if markers exist...
			a = 1
			for i = 0, num_markersOut - 1 do  -- loop through marker and region index nums
				local retval, isrgnOut, posOut, rgnendOut, nameOut, markrgnindexnumberOut, colorOut = reaper.EnumProjectMarkers3(0, i)
				if not isrgnOut then  -- if not a region...

					MarkerNum[a] = retval
					MarkerPos[a] = posOut
					MarkerCap[a] = nameOut
					a = a + 1
				end
			end
			local ButtonName = ""
			local ButtonCaption = ""
			a = 1
			-- MsgBox("Changing the labels of " .. tablelength(MarkerNum) .. " buttons.")
			for i = 1, tablelength(MarkerNum) do
				if MarkerCap[i] == ("End Special " .. a) then
					ButtonCaption = a .. " - " .. reaper.format_timestr(MarkerPos[i], "")
					ButtonName = "Marker_SermonEnd" .. a
					MsgBox(ButtonCaption)
				end
				MsgBox("ButtonName: " .. ButtonName .. "\nButtonCaption: " .. ButtonCaption)
				if ButtonName ~= nil and ButtonName ~= "" and ButtonCaption ~= nil then GUI.elms.ButtonName.caption = ButtonCaption end -- Update the button's caption
			end
		end
end
I think that I'm going about it wrong to relabel the buttons using GUI.elms.variablename.caption = ButtonCaption, but I don't know what else to do to concatenate the name and the loop number, and I really don't want to write an if/then section for each and every button if I can get away with it.

I'm getting the error: "Reaper DAW Interface GUI (For Conferences - Rev 2).lua:1218: attempt to index a nil value (field 'ButtonName')"

What am I supposed to do here?
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-14-2019, 06:32 AM   #6
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 5,883
Default

When you need to use a variable for accessing table values, it has to be written in the [] style for Lua to know that you mean "take this variable's value, not the actual string":
Code:
GUI.elms[ButtonName].caption

-- Changing the caption won't prompt a redraw by itself
GUI.elms[ButtonName]:redraw()
Lokasenna is offline   Reply With Quote
Old 05-14-2019, 04:19 PM   #7
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 289
Default

Quote:
Originally Posted by Lokasenna View Post
When you need to use a variable for accessing table values, it has to be written in the [] style for Lua to know that you mean "take this variable's value, not the actual string":
Code:
GUI.elms[ButtonName].caption

-- Changing the caption won't prompt a redraw by itself
GUI.elms[ButtonName]:redraw()
I could have sworn that I did that with the caption, but I didn't know about the :redraw part.

Thank you! To the rescue once again!
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-14-2019, 08:09 PM   #8
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 5,883
Default



The elements redraw themselves automatically in response to user events, or any time your script sets their value using :val. Changing anything else requires :redraw before it will show up, and in some cases you also have to add :init.
Lokasenna is offline   Reply With Quote
Old 05-15-2019, 03:47 PM   #9
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 289
Default

Quote:
Originally Posted by Lokasenna View Post
Changing anything else requires :redraw before it will show up, and in some cases you also have to add :init.
When are those moments (to have to add :init)?

Also, I'm having some difficulty achieving an 'active edit' situation. Currently I'm scanning the markers to update variables, and the textboxes get updated from those variables automatically. But, what I'm not able to figure out yet is when I type in the textboxes, it automatically updates the markers. What I need is a way to identify that a textbox has focus and is being typed into so that the script stops trying to update the textboxes from the markers.


The 'focus' parameter of textbox isn't what I had hoped. I had hoped that it was a flag set when a textbox has focus.
Quote:
focus Boolean. Whether the textbox is "in focus" or not, allowing users to
type. This setting is automatically updated, so you shouldn't need to
change it yourself in most cases.
How do you go about doing that?
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-15-2019, 04:36 PM   #10
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 5,883
Default

Quote:
Originally Posted by tXShooter View Post
When are those moments (to have to add :init)?
init is called for every element when the GUI window first opens so they can draw their parts to graphics buffers. Anything in a buffer is just copy/pasted when the element redraws, so if something in the buffer needs a change (the background color, say) it will have to be reinitialized so an update copy is saved there.

I'm not sure offhand which properties would require it, unfortunately. If you change a property and a redraw isn't showing the change, you'll need to reinitialize it as well.

Having said that, I'm not sure if any of the elements might break something if you do so. I'm trying to separate that sort of thing a bit better for V3.

Quote:
The 'focus' parameter of textbox isn't what I had hoped. I had hoped that it was a flag set when a textbox has focus.
That's what it should be doing - any time you see the green outline, the textbox should have .focus == true.
Lokasenna is offline   Reply With Quote
Old 05-16-2019, 03:24 PM   #11
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 289
Default

Quote:
Originally Posted by Lokasenna View Post
That's what it should be doing - any time you see the green outline, the textbox should have .focus == true.
I must be doing something wrong, and I can't seem to find anything that explains how to properly use it.

Code:
if GUI.Val("SongTitle1").focus == true then MsgBox("Title 1 has focus") end
if GUI.("SongTitle1").focus == true then MsgBox("Title 1 has focus") end

-- Winner Winner Chicken Dinner:
if GUI.elms["SongTitle1"].focus == true then MsgBox("Title 1 has focus") end
What's the proper way to write that?
Nevermind. I finally was able to figure it out (there weren't any examples to go off of anywhere).

Code:
function TextBoxHasFocus()
	for j = 1, 10 do
		for i = 1, tablelength(SongTextBoxNames) do
			local t = "Song" .. SongTextBoxNames[i] .. j
			if GUI.elms[t].focus == true then
				return true
			end
		end
	end
	return false
end
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter 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 11:51 PM.


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