Old 12-18-2019, 04:23 AM   #641
tompad
Human being with feelings
 
Join Date: Jan 2010
Location: Fjugesta, Sweden
Posts: 415
Default Lokasenna GUI v2 - how to make a progressbar with slider

Hi there all LGUIv2-users!

I am trying to make a progress bar of a slider for my Practice Coach-script
and I have sort of managed to do it BUT there is one issue. When I start
script everything is correct - slider starts in zero position and is rising
to max position and when max is reached the slider resets to zero. And now
ladies and gentlemens the problem arise! Next time the loop is run the slider
starts at a minus-position outside of the slider! I cant figure out where the
negative numbers come from....

Code:
GUI.New("Slider1", "Slider", {
  z = 11,
  x = 8,
  y = 8,
  w = 200,
  caption = "",
  min = 10,
  max =0,
  defaults = {0},
  inc = 1,
  dir = "v",
  font_a = 3,
  font_b = 4,
  col_txt = "txt",
  col_fill = "elm_fill",
  bg = "wnd_bg",
  show_handles = false,
  show_values = false,
  cap_x = 0,
  cap_y = 0
})


--other code.......


function startButton ()
  if buttonEnabled then
    startTime = reaper.time_precise()
    endTime = startTime + practiceTime[i]
    setBPM()
    countDownTimer()
    GUI.elms.Start_Cont_Button.caption = "...."
    reaper.Main_OnCommandEx( 40630, 0, 0 )
    reaper.OnPlayButton()
    buttonEnabled = false
    i = i + 1
    stepsLeft = stepsLeft - 1
    GUI.Val("StepsLeft_Label", "Steps left: " .. stepsLeft)
  else
    --...nothing should happen - button is disabled
  end
end


function countDownTimer()
  if (reaper.time_precise() <= endTime) then
    reaper.defer(countDownTimer)
    progress = (endTime - reaper.time_precise())
    GUI.Val("Slider1", progress )
  else
    reaper.OnStopButton()
    GUI.Val("Slider1", 10 )
    buttonEnabled = true
    if i <= 8 then
      notFinished = true
      GUI.elms.Start_Cont_Button.caption = "Continue"
      GUI.elms.Start_Cont_Button:redraw()
    else
      notFinished = false
      GUI.elms.Start_Cont_Button.caption = "Start"
      GUI.elms.Start_Cont_Button:redraw()
      stepsLeft = 8
      GUI.Val("StepsLeft_Label", "Steps left: " .. stepsLeft)
      i = 1
    end
    if autoContinue and notFinished then
      autoContMB = GUI.Val("AutoContMB")
      pauseTime = autoContMB * 5
      startTime2 = endTime
      endTime2 = startTime2 + pauseTime
      countDownTimer2()
    end
  end
end

function countDownTimer2 ()
  if (reaper.time_precise() <= endTime2) then
    reaper.defer(countDownTimer2)
  else
    startButton()
  end
end
I am testing this on my developer computer with Linux and the latest LGUIv2 and Reaper 6.0.

I am not sure my solution is the best one - if you have another approach
to a progressbar with LGUIv2 I love to hear from you!

Regards
Thomas
__________________
ToDoList Obliques MusicMath Donation Mark4celeste Frid i ditt hjärta Eve & the Fisherman on Spotify
tompad is offline   Reply With Quote
Old 12-18-2019, 04:48 AM   #642
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 281
Default

Thanks again!

I have found another problem with this approach. Would like your opinion please. Everytime a user selects a preset, the UI changes reflecting each slider, button values. Good.

Because the menubox preset selector is inside the main loop, everytime i try to change a parameter after loading a preset the UI automatically updates to the preset data, reading it from the Extsate and applying it to the elemetns continuously...which makes it impossible to edit any preset XD

So, if i want to keep it simple with just the menubox, is there a way to call a function from the loop but only once? Ideally updating the GUI with the preset data should happen only when the menubox selector changes, not on every loop.

This is probably a basic loop misunderstanding so excuse me if the answer is too obvious. :blush:
reapero is offline   Reply With Quote
Old 12-18-2019, 09:49 AM   #643
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,530
Default

Quote:
Originally Posted by tompad View Post
Hi there all LGUIv2-users!

I am trying to make a progress bar of a slider for my Practice Coach-script
and I have sort of managed to do it BUT there is one issue. When I start
script everything is correct - slider starts in zero position and is rising
to max position and when max is reached the slider resets to zero. And now
ladies and gentlemens the problem arise! Next time the loop is run the slider
starts at a minus-position outside of the slider! I cant figure out where the
negative numbers come from....
Can't say for sure without the rest of the code, but my guess would be this:
Code:
progress = (endTime - reaper.time_precise())
GUI.Val("Slider1", progress )
The Slider's val method expects a multiple of [i]inc/i] within its range - 0 to 10, in this case. I'm not sure what happens if you give it something like 5.125, but even assuming it does the right thing there you're still passing in the time difference rather than a value from 0 to 10. Try:
Code:
    local progress = endTime - reaper.time_precise()
    local length = endTime - startTime
    local progress = math.floor(progress / length * GUI.elms.Slider1.steps)
    GUI.Val("Slider1", progress )
Quote:
I am not sure my solution is the best one - if you have another approach to a progressbar with LGUIv2 I love to hear from you!
You could simplify things by just using a Frame and overriding its draw method to draw a progress bar using a percentage of its full width. Then you wouldn't have to worry about slider steps, range, etc.
Lokasenna is offline   Reply With Quote
Old 12-18-2019, 09:58 AM   #644
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,530
Default

Quote:
Originally Posted by reapero View Post
Because the menubox preset selector is inside the main loop
I'm confused; why is the preset selector in your main loop? You should just have to attach your handler to the menubox so it's run every time the user chooses a preset. Something like:
Code:
local function updateOtherElements()
  ...
end

function GUI.elms.myMenuBox:onmouseup()
  GUI.Menubox.onmouseup(self)

  updateOtherElements()
end

function GUI.elms.myMenuBox.onmouseup()
  GUI.Menubox.onwheel(self)

  updateOtherElements()
end
Quote:
So, if i want to keep it simple with just the menubox, is there a way to call a function from the loop but only once? Ideally updating the GUI with the preset data should happen only when the menubox selector changes, not on every loop.
If you do need to have it in the main loop, for whatever reason, then something like this will do the trick:
Code:
local presetWasChanged = false

function GUI.elms.myMenuBox:onmouseup()
  GUI.Menubox.onmouseup(self)
  presetWasChanged = true
end

function GUI.elms.myMenuBox.onmouseup()
  GUI.Menubox.onwheel(self)
  presetWasChanged = true
end

local function mainLoop()
  if presetWasChanged then
    -- Update the other elements
    presetWasChanged = false
  else
    -- Do something else
  end

  reaper.defer(mainLoop)
end

mainLoop()
Lokasenna is offline   Reply With Quote
Old 12-18-2019, 10:17 AM   #645
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 281
Default

Quote:
Originally Posted by Lokasenna View Post
I'm confused; why is the preset selector in your main loop? You should just have to attach your handler to the menubox so it's run every time the user chooses a preset. Something like:
[code]local function updateOtherElements()
...
Allright, i completely did it wrong then. I didnt connect any onmouseup() to anything and since i only got a static value from the menubox (the one when the script initializes) i thought the way to get it was to put it inside the main loop.

I think i got confused by not seeing those methods in the wiki subpage for the menubox class:

https://github.com/jalovatt/Lokasenna_GUI/wiki/2.00-Menubox

I guess those are inherited from other classes. Would adding this info there make sense or is it just common sense i failed to understand? Maybe its already explained somewhere?

Thanks!
reapero is offline   Reply With Quote
Old 12-18-2019, 10:27 AM   #646
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,530
Default

They aren't covered in the documentation, no. Have a look at Example - Adding a Main loop, working with Z layers, and Rewriting Methods.lua for a very similar use case to what you're doing though.

v3 will make them much easier and I'll be sure to actually document them this time
Lokasenna is offline   Reply With Quote
Old 12-18-2019, 10:39 AM   #647
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 281
Default

Sure. Looking forward to it!
reapero is offline   Reply With Quote
Old 12-20-2019, 04:53 AM   #648
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 281
Default

I cant set a checkbox to false using:

Code:
GUI.Val("My_checkbox",false)
Setting it to true works though. Bug maybe?
reapero is offline   Reply With Quote
Old 12-20-2019, 09:50 AM   #649
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,530
Default

What version of the library are you using? It is a bug, but one that I added a fix for a month ago. (v2.16.10)

Here's the code; it's entirely possible I made a logic error:
Code:
  if newval ~= nil then
    if type(newval) == "table" then
      for k, v in pairs(newval) do
        self.optsel[tonumber(k)] = v
      end
      self:redraw()
    elseif type(newval) == "boolean" and #self.optarray == 1 then
      self.optsel[1] = newval
      self:redraw()
    end
  else
  ...
Lokasenna is offline   Reply With Quote
Old 12-20-2019, 02:50 PM   #650
Buy One
Human being with feelings
 
Join Date: Sep 2019
Posts: 114
Default

Through ReaTrak i finally have discovered the possibility of making custom toolbars and drop-down menus with this great Lokasenna's library.

My question is if there's a way to define in the code line breaks for menu items with long names.
Buy One is offline   Reply With Quote
Old 12-20-2019, 03:01 PM   #651
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,530
Default

Nope. Reaper uses native popup menus on Mac and Windows, and a pretend-native one on Linux, and none of those allow multiline items as far as I've ever seen.

In other news, v3 of the library will add a module specifically for making dealing with menus less of a hassle; no more parsing the string yourself, filtering out separators, etc.
Lokasenna is offline   Reply With Quote
Old 12-20-2019, 03:06 PM   #652
Buy One
Human being with feelings
 
Join Date: Sep 2019
Posts: 114
Default

I see, thank you
Buy One is offline   Reply With Quote
Old 12-22-2019, 02:42 AM   #653
tompad
Human being with feelings
 
Join Date: Jan 2010
Location: Fjugesta, Sweden
Posts: 415
Default

Quote:
Originally Posted by Lokasenna View Post
The Slider's val method expects a multiple of [i]inc/i] within its range - 0 to 10, in this case. I'm not sure what happens if you give it something like 5.125, but even assuming it does the right thing there you're still passing in the time difference rather than a value from 0 to 10. Try:
Code:
    local progress = endTime - reaper.time_precise()
    local length = endTime - startTime
    local progress = math.floor(progress / length * GUI.elms.Slider1.steps)
    GUI.Val("Slider1", progress )
Absolutly brilliant!! That did it!

Quote:
You could simplify things by just using a Frame and overriding its draw method to draw a progress bar using a percentage of its full width. Then you wouldn't have to worry about slider steps, range, etc.
I looked a bit on Frame but found that Slider looked better so Slider it be :-)

Thanks Lokasenna! Excellent solutions as always.
I wish you a Merry Christmas and a Happy New Year! Salut!
__________________
ToDoList Obliques MusicMath Donation Mark4celeste Frid i ditt hjärta Eve & the Fisherman on Spotify
tompad is offline   Reply With Quote
Old 12-23-2019, 04:05 AM   #654
reapero
Human being with feelings
 
Join Date: Aug 2011
Posts: 281
Default

Quote:
Originally Posted by Lokasenna View Post
What version of the library are you using? It is a bug, but one that I added a fix for a month ago. (v2.16.10)
I must be on the latest one since i update Reapack quite often but..how do i check which exact version i have? At the first comments of the Core.lua file it says "Lokasenna_GUI 2.9 Core functionality"

Inspecting the file "Class - Options.lua" here i can see the snippet of code you just posted as it is though, no errors, yet i still cant set a single option checklist to false using GUI.Val.

EDIT: ok, I can see i have 2.16.10 in the Browse packages window of Reapack

Last edited by reapero; 12-23-2019 at 04:36 AM.
reapero is offline   Reply With Quote
Old 12-27-2019, 10:39 AM   #655
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,530
Default

Whoops; the bug fix only worked if you set the value directly using GUI.elms.my_checklist:val(false). Updating now.
Lokasenna is offline   Reply With Quote
Old 12-28-2019, 01:09 PM   #656
Buy One
Human being with feelings
 
Join Date: Sep 2019
Posts: 114
Default

Maybe my question is not specific for the GUI library and applies to general scripting techniques, but since it's inspired by my experience with the Menubar element i'll dare to ask here

Is there a way, preferably simple, since i'm coding illiterate, to force the drop-down menu to stay on after a menu item has been clicked?
Buy One is offline   Reply With Quote
Old 12-28-2019, 02:58 PM   #657
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,530
Default

Nope.

The dropdown menu is completely handled by Reaper; scripts just tell it where the labels, folders, separators, etc are. Scripts are also paused until the user picks something.
Lokasenna is offline   Reply With Quote
Old 12-28-2019, 03:44 PM   #658
Buy One
Human being with feelings
 
Join Date: Sep 2019
Posts: 114
Default

OK, thank you for the info
Buy One is offline   Reply With Quote
Old 01-08-2020, 10:44 PM   #659
MusoBob
Human being with feelings
 
MusoBob's Avatar
 
Join Date: Sep 2014
Posts: 1,198
Default

If you could you could get something like this for Lua scripting in Ardour would be very helpful as it's very limited without a GUI.
https://discourse.ardour.org/t/lua-s...brary/102423/2
__________________
ReaTrakStudio Chord Track for Reaper forum
www.reatrak.com
MusoBob is offline   Reply With Quote
Old 01-09-2020, 07:26 AM   #660
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,530
Default

Quote:
Originally Posted by MusoBob View Post
If you could you could get something like this for Lua scripting in Ardour would be very helpful as it's very limited without a GUI.
https://discourse.ardour.org/t/lua-s...brary/102423/2
I don't know C++ either.
Lokasenna is offline   Reply With Quote
Old 01-11-2020, 04:46 AM   #661
Fabian
Human being with feelings
 
Fabian's Avatar
 
Join Date: Sep 2008
Location: Sweden
Posts: 5,587
Default Strange behavior on resize...

Maybe I am doing something wrong, but I get very strange behavior on resize.



First of all, I have to click one of the text boxes before getting any response to the resize. But then, after having clicked on, after resize some strange frame is painted on the non-focused text box.

This code
Code:
-- Standard code for loading the library removed

GUI.name = SCRIPT_NAME
GUI.x, GUI.y, GUI.w, GUI.h = ORIG_X, ORIG_Y, ORIG_W, ORIG_H
GUI.anchor, GUI.corner = "screen", "TL"

GUI.New("txted_text", "TextEditor", 1, 10, 10, ORIG_W-20, (ORIG_H-20)/2, "Select an item\nor two\nor three\nor everything\n\nin the list\nand click the button!")
GUI.New("texted2", "TextEditor", 1, 10, 20+(ORIG_H-20)/2, ORIG_W-20, (ORIG_H-20)/2, "Another text editor...")

function resize()
	GUI.elms.txted_text.w = GUI.cur_w - 20
	GUI.elms.texted2.w = GUI.cur_w - 20
end -- resize()

GUI.onresize = resize
GUI.Init()
GUI.Main()
This is v 2.16.11
__________________
// MVHMF
I never always did the right thing, but all I did wasn't wrong...
Fabian is offline   Reply With Quote
Old 01-12-2020, 09:03 AM   #662
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,530
Default

When you resize the elements you also need to reinitialize them. Should just be:
Code:
function resize()
	GUI.elms.txted_text.w = GUI.cur_w - 20
	GUI.elms.texted2.w = GUI.cur_w - 20

  GUI.elms.txted_text:init()
  GUI.elms.texted2:init()
end
For most of the elements, when they're initialized they take a graphics buffer and draw their various parts to it. In the text editor's case, it draws its frame and then, right next to it, the same thing with the green "active" highlight.

When the GUI tells it to draw itself, it copies the appropriate area from that buffer. What you're seeing is it copying based on the new width but the source image was drawn at the original size, so it ends up taking some of the highlighted one as well.

Edit: You'll need to :redraw() both elements as well, I think, to have it updated right away.

Last edited by Lokasenna; 01-12-2020 at 09:08 AM.
Lokasenna is offline   Reply With Quote
Old 01-13-2020, 08:54 PM   #663
dsyrock
Human being with feelings
 
dsyrock's Avatar
 
Join Date: Sep 2018
Location: China
Posts: 229
Default

Is there any way to refresh the menubox option?

For example, the origin option is "A,B,C". Now if I change it to "A,B,C,D,E", how can I change the GUI of menubox without re-runing?
dsyrock is online now   Reply With Quote
Old 01-14-2020, 07:25 AM   #664
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,530
Default

Quote:
Originally Posted by dsyrock View Post
Is there any way to refresh the menubox option?

For example, the origin option is "A,B,C". Now if I change it to "A,B,C,D,E", how can I change the GUI of menubox without re-runing?
Should be:
Code:
myMenubox.optarray = {"A", "B", "C", "D", "E"}
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:35 AM.


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