|
|
|
02-20-2019, 09:54 AM
|
#401
|
Human being with feelings
Join Date: Jul 2010
Location: Slovakia
Posts: 2,588
|
Quote:
Originally Posted by Lokasenna
Nice ideas, thanks.
Why no shadows, out of curiosity? I've always found them really useful.
|
They are distracting and a user (me) subconsciously think what is their function, what is clickable, what is not, do they represent something? To much visual information.
These days you don't have shadows like this anywhere, they are not necessary for good UI navigation anymore since people get used to computer screens. I have seen a good shadow implementation in Davinci Resolve, where they use wider shadows to indicate which panel goes over which in terms of layering.
|
|
|
02-20-2019, 10:54 AM
|
#402
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,621
|
@lokasenna
Are you interested in cooperating for the rewrite? I'm also planning a Gui-Engine for my Ultraschall-API with event-management-system, separation of GUI and code, multiple gui-windows openable from one script and such, currently building the technical basis for that into my API.
Maybe we could do one Gui to rule them all. Especially, as you are so deep into the whole gfx-thing already, this would be awesome...
|
|
|
02-20-2019, 11:07 AM
|
#403
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by mespotine
@lokasenna
Are you interested in cooperating for the rewrite? I'm also planning a Gui-Engine for my Ultraschall-API with event-management-system, separation of GUI and code, multiple gui-windows openable from one script and such, currently building the technical basis for that into my API.
Maybe we could do one Gui to rule them all. Especially, as you are so deep into the whole gfx-thing already, this would be awesome...
|
Definitely worth talking about, absolutely.
|
|
|
02-20-2019, 11:24 AM
|
#404
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by bFooz
They are distracting and a user (me) subconsciously think what is their function, what is clickable, what is not, do they represent something? To much visual information.
These days you don't have shadows like this anywhere, they are not necessary for good UI navigation anymore since people get used to computer screens. I have seen a good shadow implementation in Davinci Resolve, where they use wider shadows to indicate which panel goes over which in terms of layering.
|
I actually find the modern "everything is flat" style frustrating specifically because you *can't* tell which things are clickable, where one area ends, etc. There are times when I have multiple apps and windows open and I have to stop for a second to figure out which one an element belongs to.
One thing I'm hoping to add is a global user config so you can adjust the theming to your taste, in which case "shadow size" will definitely be an option.
Last edited by Lokasenna; 02-20-2019 at 11:43 AM.
|
|
|
02-20-2019, 11:33 AM
|
#405
|
Human being with feelings
Join Date: Oct 2017
Location: Black Forest
Posts: 5,054
|
Quote:
Originally Posted by Lokasenna
I actually find the modern "everything is flat" style frustrating specifically because you *can't* tell which things are clickable, where one area ends, etc. There are times when I have multiple apps and windows open and I have to stop for a second to figure out which one an element belongs to.
|
I absolutely agree with that.
And a collab between you and mespo sounds amazing
|
|
|
02-21-2019, 06:20 AM
|
#406
|
Human being with feelings
Join Date: Jan 2010
Location: Fjugesta, Sweden
Posts: 811
|
Collab! That would make a great thing even greater! (Is this possible?);-)
I would also love to see an import-func(save/load) to GUI Builder!
Theming of GUI?
|
|
|
02-21-2019, 11:12 AM
|
#407
|
Human being with feelings
Join Date: Jun 2007
Location: Terra incognita
Posts: 7,670
|
Quote:
Originally Posted by Lokasenna
I actually find the modern "everything is flat" style frustrating specifically because you *can't* tell which things are clickable, where one area ends, etc.
|
Same here sometimes. For me it makes it usually quicker to see immediately if something is actually a clickable/adjustable control or e.g. just a shown value or a parameter name.
Quote:
One thing I'm hoping to add is a global user config so you can adjust the theming to your taste, in which case "shadow size" will definitely be an option.
|
That would be nice.
|
|
|
02-21-2019, 11:40 AM
|
#408
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by tompad
Collab! That would make a great thing even greater! (Is this possible?);-)
|
I'm hoping for collaborators, absolutely. I'm working on modularizing the existing codebase so it's easier to rewrite separate parts without breaking everything; once that's done, I'll put it on a repo and try to figure out a collaboration process.
Quote:
I would also love to see an import-func(save/load) to GUI Builder!
|
Yes please.
Users being able to set their own global fonts and colors will definitely happen, similar to how Radial Menu does it.
|
|
|
03-03-2019, 03:58 PM
|
#409
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,619
|
Quote:
Originally Posted by mespotine
multiple gui-windows openable from one script and such
|
Is this possible without resorting to spawning multiple scripts under-the-hood by triggering actions? It's not too clear how to do this otherwise as gfx.init() assumes a global context.
I've wished for this for Reaticulate which needs to be able to open a separate window for the bank editor, but for now I'm just invoking a separate action which runs a separate instance. It'd be nice to consolidate this into one script "process" context as the UI library is starting to get pretty weighty.
|
|
|
03-03-2019, 04:52 PM
|
#410
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by tack
Is this possible without resorting to spawning multiple scripts under-the-hood by triggering actions? It's not too clear how to do this otherwise as gfx.init() assumes a global context.
|
mespotine's Ultraschall API has a bunch of functions for opening and running multiple windows. I haven't had a chance to play with them yet, but I'm planning for the next version of my GUI to work with it.
Quote:
It'd be nice to consolidate this into one script "process" context as the UI library is starting to get pretty weighty.
|
Step 1: Don't have all the code in one file, especially the different widgets that a given script might not need.
Step 2: Don't load files unless the script needs them.
The current version of my GUI does this for the widgets, but I've already refactored the next release to do it for pretty much everything.
Optional Step 3: Just use my GUI instead. :P If you're interested, I'm happy to help with porting everything. Even just using the engine of mine with your own custom classes might save you a lot of work, I think.
|
|
|
03-03-2019, 05:46 PM
|
#411
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,619
|
Quote:
Originally Posted by Lokasenna
mespotine's Ultraschall API has a bunch of functions for opening and running multiple windows.
|
Ah cool, thanks for the tip. I'll check it out.
Quote:
Originally Posted by Lokasenna
Step 1: Don't have all the code in one file, especially the different widgets that a given script might not need.
Step 2: Don't load files unless the script needs them.
|
Most of the stuff in that file is actually core functionality. The widgets themselves are pretty minimal in comparison. Load times are pretty insignificant (os.clock() doesn't have enough resolution to measure it) so I'm not motivated to split it up into separate files yet except to make development easier (and I'm getting to that point).
I was more concerned about memory overhead given the duplication across instances. But I suppose relative to everything else going on in a DAW it's minimal.
Quote:
Originally Posted by Lokasenna
Optional Step 3: Just use my GUI instead. :P If you're interested, I'm happy to help with porting everything. Even just using the engine of mine with your own custom classes might save you a lot of work, I think.
|
I did consider it actually, but ultimately decided I was just much too invested in what I call rtk (the "Reaper toolkit" which is heavily inspired by gtk+ in its basic design). Your first release happened after I'd already spent about a year working on Reaticulate (and during that period worked on rtk to support it).
The main issue I have with your current version is the fixed grid system. Fluid layouts are important to me, for example being able to achieve something like this:
https://www.youtube.com/watch?v=mEg0wptXt1E
That's actually where most of the code is, in the container/box system and the scrollable viewport, plus some other scaffolding to support things like inter-widget drag-and-drop. That foundation is relatively mature right now and I don't want to abandon it -- even though your library clearly does have a significantly more featureful set of widgets to choose from.
Possibly you're looking at a dynamic layout system in your rewrite? If so I might take another look at that time. Meanwhile, I need to focus on getting the next major release of Reaticulate out the door.
|
|
|
03-03-2019, 06:21 PM
|
#412
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Fair enough.
My GUI doesn't have a fixed grid system, it's just that none of the widgets have code to resize/reposition themselves. There are global and widget-level hooks for the window being resized, so you would just have to add one function to loop through all of the widgets and recalculate from their original x/y/w/h versus the current window dimensions.
Well, and then fix the widgets that have some dimensions hardcoded or calculated when you first create them... Dynamic positioning is easy-peasy though.
I would like to make dynamic sizing easier in the new version though - one item on my to-do list is to borrow the "flow" logic White Tie has in the Default 5 theme so the widgets can push each other around and wrap as needed.
Last edited by Lokasenna; 03-03-2019 at 06:29 PM.
|
|
|
03-03-2019, 06:47 PM
|
#413
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,619
|
Quote:
Originally Posted by Lokasenna
Well, and then fix the widgets that have some dimensions hardcoded or calculated when you first create them... Dynamic positioning is easy-peasy though.
|
There's devils in them there details.
The box system I implemented (which is inspired by gtk+'s hbox/vbox) was surprisingly challenging. Boxes which are sized only as much as needed to fit their children (shrink-wrapped); boxes that can be expanded to fit their parent containers; cells within boxes that can have different ratios in their consumption of available space; propagating that available space to child widgets or not, and if not then justifying the children within the cells; supporting all that in scrollable viewports. And then I further stacked the deck against myself by wanting to support dynamically-determined but fixed-position widgets (think position:fixed in CSS), which you can see in that red "Fixed position widget" in the video.
I ended up spending a surprising amount of time getting that right (or at least what I think is right). Surprising because I too figured it couldn't be all that hard.
Quote:
Originally Posted by Lokasenna
I would like to make dynamic sizing easier in the new version though - one item on my to-do list is to borrow the "flow" logic White Tie has in the Default 5 theme so the widgets can push each other around and wrap as needed.
|
That's a very cool idea. I can definitely see use-cases for that.
|
|
|
03-03-2019, 06:53 PM
|
#414
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by tack
There's devils in them there details.
The box system I implemented (which is inspired by gtk+'s hbox/vbox) was surprisingly challenging. Boxes which are sized only as much as needed to fit their children (shrink-wrapped); boxes that can be expanded to fit their parent containers; cells within boxes that can have different ratios in their consumption of available space; propagating that available space to child widgets or not, and if not then justifying the children within the cells; supporting all that in scrollable viewports. And then I further stacked the deck against myself by wanting to support dynamically-determined but fixed-position widgets (think position:fixed in CSS), which you can see in that red "Fixed position widget" in the video.
|
Nice. I'm adding a note to my idea list to look at your code for a potential "do all the resizing things" module.
|
|
|
03-03-2019, 06:57 PM
|
#415
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,619
|
Quote:
Originally Posted by Lokasenna
Nice. I'm adding a note to my idea list to look at your code for a potential "do all the resizing things" module.
|
Cool. If there's anything in there you're able to lift, that's icing on the cake. Let me know if you find bugs.
Container, Box (subclasses Container), VBox and HBox (which subclass Box) are the ones to look at.
|
|
|
03-03-2019, 07:00 PM
|
#416
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,619
|
The important thing is that the architecture needs to support the notion of reflowing. It's not just when the window resizes: any time something changes its size within the scene graph, it needs to trigger a reflow.
|
|
|
03-03-2019, 11:16 PM
|
#417
|
Human being with feelings
Join Date: Jan 2010
Location: Fjugesta, Sweden
Posts: 811
|
Quote:
Originally Posted by tack
|
Ooooooh myyyyyy Gooooooooooood!
This is awesome, Tack!
|
|
|
03-28-2019, 10:49 PM
|
#418
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
can't get value from gui.Val
I'm trying to test a method by modifying one of the example scripts (as little as possible) It just adds a send or two, and changes a parameter in a jsfx.
But however I try to get the value of the slider, It always crashes the script, and the trace doesn't show the value of it.
Is there a simpler way to get the value of a slider than to override mouse methods anyway? I couldn't find one. The button object has a built-in method, but none of the others seem to.... I'm used to adding a listener, but I don't see any equivalent here.
I also tried calling my method with self.Val as an argument from within the double-click method, instead of trying to get it from within my method and that allowed me to get the slider's value printed to the console before the crash.... it said 'nil'.
Here's the trace:
Code:
Test_Attempt_2.lua:59: in upvalue 'setNotesource'
Test_Attempt_2.lua:179: in method 'ondoubleclick'
Core.lua:843: in field 'Update'
Core.lua:434: in field 'Main_Update_Elms'
Core.lua:301: in function <...am Scripts\Development\Lokasenna_GUI v2\Library\Core.lua:297>
[C]: in function 'xpcall'
Core.lua:297: in function <...am Scripts\Development\Lokasenna_GUI v2\Library\Core.lua:296>
Lokasenna_GUI: v2.16.3
Reaper: 5.972/x64
Platform: Win64
And here's the code:
Code:
-- NoIndex: true
--[[
Lokasenna_GUI
- Using the Main loop to monitor and interact with things in Reaper
- Using z layers and related functions to move elements around
- Changing elements' methods for your own purposes
]]--
-- 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")()
dofile(reaper.GetResourcePath().."/UserPlugins/ultraschall_api.lua")
GUI.req("Classes/Class - Label.lua")()
GUI.req("Classes/Class - Slider.lua")()
GUI.req("Classes/Class - Frame.lua")()
-- If any of the requested libraries weren't found, abort the script.
if missing_lib then return 0 end
------------------------------------
-------- Data + functions ----------
------------------------------------
-- Pre-declaring this so every function has access to it
local tr
local function update_pan()
--reaper.SetMediaTrackInfo_Value( tr, "D_PAN", GUI.Val("sldr_pan")/100 )
end
local function addMidiReceive(tracknumber,srcChan)
--set to midi input (1024)
added = ultraschall.AddTrackAUXSendReceives(tracknumber,srcChan,
0,0,0,0,0,0,1,1,-1,1024,-1,false)
if added then return added
else ultraschall.print2("problem setting midi receive from track "
..tostring(srcChan).." to track "..tostring(tracknumber))
end
end
local function setNotesource()
nsIndex = gui.Val("sldr_pan")
reaper.ShowConsoleMsg("nsrc = "..tostring(nsIndex))
tracknumber = 16
PIANO = 1
ROLI = 2
DUAL = 3
NONE = 4
OUTPUT_A_TRACKNUM = 1
OUTPUT_B_TRACKNUM = 2
OUTPUT_C_TRACKNUM = 3
OUTPUT_D_TRACKNUM = 4
PIANO_TRACKNUM = 5
ROLI_TRACKNUM = 6
MIDICHSTRIP_SLOT_NUM = 2
NS_SELECT_PARAM = 11
--Get track
track = reaper.GetTrack(0,tracknumber)
if track == nil then ultraschall.print2("invalid track number")
end
--ultraschall.print2("track = "..tostring(tracknumber))
--Get list of sends
count_Receives = ultraschall.CountTrackAUXSendReceives(tracknumber)
--check through for those that are midi enabled
for i = 0, count_Receives do
_,_,_,_,_,_,_,_,_,_,hasMIDI,_ = ultraschall.GetTrackAUXSendReceives(tracknumber, i)
if hasMIDI == 1024 then --setting for all midi enabled
--remove these sends
removed = ultraschall.DeleteTrackAUXSendReceives(tracknumber, i, false)
end
end
--add new send(s) to track 1-kx8,2-roli,1&2 dual, none for FX (this is also our check for isFX)
if nsIndex == PIANO then
addMidiReceive(tracknumber,PIANO_TRACKNUM)
elseif nsIndex == ROLI then
addMidiReceive(tracknumber,ROLI_TRACKNUM)
elseif nsIndex == DUAL then
addMidiReceive(tracknumber,ROLI_TRACKNUM)
addMidiReceive(tracknumber,PIANO_TRACKNUM)
else --do nothing it's an effect... or should we do something?
end
--set midiChStrip value for input type
--reaper.ShowConsoleMsg()
reaper.TrackFX_SetParam(track,MIDICHSTRIP_SLOT_NUM,NS_SELECT_PARAM,nsIndex)
ultraschall.ShowLastErrorMessage()
end
------------------------------------
-------- Window settings -----------
------------------------------------
GUI.name = "Example - Main, Z, and Methods"
GUI.x, GUI.y, GUI.w, GUI.h = 0, 0, 300, 128
GUI.anchor, GUI.corner = "mouse", "C"
------------------------------------
-------- GUI Elements --------------
------------------------------------
--[[
Frame z, x, y, w, h[, shadow, fill, color, round]
Label z, x, y, caption[, shadow, font, color, bg]
Slider z, x, y, w, caption, min, max, defaults[, inc, dir]
]]--
--GUI.New("lbl_track", "Label", 1, 96, 8, "No track selected!", true, 2, "red")
--GUI.New("frm_track", "Frame", 2, 0, 0, 300, 128, false, true, "faded", 0)
GUI.New("sldr_pan", "Slider", 3, 88, 64, 128, "First selected track's NS:", 1, 4, 1, 1, "h")
-- Layer 5 will never be shown or updated
-- (See the Main function below)
GUI.elms_hide[5] = true
------------------------------------
-------- Method overrides ----------
------------------------------------
-- Class methods can be overwritten, either at the class level or
-- for individual elements.
-- You can also easily append your own code to the stock methods:
function GUI.elms.sldr_pan:onmousedown()
-- Run the slider's normal method
GUI.Slider.onmousedown(self)
-- Note that we have to call the method as a function here; we
-- can't use the : syntax because sldr_pan's 'self' needs to be
-- passed on as a value. If we used a :, it would pass GUI.Slider
end
function GUI.elms.sldr_pan:ondrag()
GUI.Slider.ondrag(self)
end
function GUI.elms.sldr_pan:onwheel()
GUI.Slider.onwheel(self)
end
function GUI.elms.sldr_pan:ondoubleclick()
GUI.Slider.ondoubleclick(self)
setNotesource()
--setNotesource(self.Val)
end
------------------------------------
-------- Main loop -----------------
------------------------------------
-- This will be run on every update loop of the GUI script; anything you would put
-- inside a reaper.defer() loop should go here. (The function name doesn't matter)
local function Main()
end
GUI.Init()
-- Tell the GUI library to run Main on each update loop
-- Individual elements are updated first, then GUI.func is run, then the GUI is redrawn
GUI.func = Main
-- How often (in seconds) to run GUI.func. 0 = every loop.
GUI.freq = 0
GUI.Main()
|
|
|
03-29-2019, 06:09 AM
|
#419
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Line 59 - you've got GUI in lowercase.
It's possible to add listeners by overriding each of the element's input methods. You do have to be aware of what arguments the GUI is passing in each of them and make sure you provide them to the original method yourself (see the wheel example below).
Code:
function my_slider:onmouseup()
GUI.Slider.onclick(self)
-- run your own code here
end
function my_slider:ondrag()
GUI.Slider.ondrag(self)
-- run your own code here
end
function my_slider:onwheel(inc)
GUI.Slider.onwheel(self, inc)
-- run your own code here
end
I'm hoping to make it easier for v3.
|
|
|
03-29-2019, 07:55 AM
|
#420
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
Quote:
Originally Posted by Lokasenna
Line 59 - you've got GUI in lowercase.
|
DOH!!!!
|
|
|
03-29-2019, 08:58 AM
|
#421
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
Okay, moving right along now....
I can't figure out why my radio button object is sending a value of '1', regardless of which option is selected...
I also can't figure out why the slider defaults to 19 instead of 16, and why it's slider graphic is backwards....
Thanks as always!
Code:
-- 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")()
dofile(reaper.GetResourcePath().."/UserPlugins/ultraschall_api.lua")
GUI.req("Classes/Class - Slider.lua")()
GUI.req("Classes/Class - Options.lua")()
-- If any of the requested libraries weren't found, abort the script.
if missing_lib then return 0 end
local function addMidiReceive(srcChan,tracknumber)
--set to midi input (1024)
added = ultraschall.AddTrackAUXSendReceives(srcChan,tracknumber,
0,0,0,0,0,0,1,1,-1,1024,-1,false)
if added then return added
else ultraschall.print2("problem setting midi receive from track "
..tostring(srcChan).." to track "..tostring(tracknumber))
end
end
local function removeMIDISend(midiSourceTrack,destTrack)
sendCount = ultraschall.CountTrackAUXSendReceives(midiSourceTrack)
for sendNum = 0, sendCount do
dest,_,_,_,_,_,_,_,_,_,_,_ = ultraschall.GetTrackAUXSendReceives(destTrack, sendNum)
if dest == destTrack then
removed = ultraschall.DeleteTrackAUXSendReceives(midiSourceTrack, sendNum, false)
end
end
end
local function setNotesource()
nsIndex = GUI.Val("nsNum")
tracknumber = 16 -- GUI.Val("sldr_track")
--reaper.ShowConsoleMsg("track = "..tostring(tracknumber))
reaper.ShowConsoleMsg("nsIndex = "..tostring(nsIndex).."\n")
PIANO = 1
ROLI = 2
DUAL = 3
NONE = 4
OUTPUT_A_TRACKNUM = 1
OUTPUT_B_TRACKNUM = 2
OUTPUT_C_TRACKNUM = 3
OUTPUT_D_TRACKNUM = 4
PIANO_TRACKNUM = 5
ROLI_TRACKNUM = 6
MIDICHSTRIP_SLOT_NUM = 1
NS_SELECT_PARAM = 11
--Get track
track = reaper.GetTrack(0,tracknumber)
if track == nil then ultraschall.print2("invalid track number")
end
--Get list of sends
removeMIDISend(PIANO_TRACKNUM,tracknumber)
removeMIDISend(ROLI_TRACKNUM,tracknumber)
--[[
count_Receives = ultraschall.CountTrackAUXSendReceives(tracknumber)
--check through for those that are midi enabled
for i = 0, count_Receives do
_,_,_,_,_,_,_,_,_,_,hasMIDI,_ = ultraschall.GetTrackAUXSendReceives(tracknumber, i)
reaper.ShowConsoleMsg("receive ="..tostring(i).."hasMIDI = "..tostring(hasMIDI))
if hasMIDI == 1024 then --setting for all midi enabled
--remove these sends
removed = ultraschall.DeleteTrackAUXSendReceives(tracknumber, i, false)
end
end]]--
--add new send(s) to track 1-kx8,2-roli,1&2 dual, none for FX (this is also our check for isFX)
if nsIndex == PIANO then
addMidiReceive(tracknumber,PIANO_TRACKNUM)
elseif nsIndex == ROLI then
addMidiReceive(tracknumber,ROLI_TRACKNUM)
elseif nsIndex == DUAL then
addMidiReceive(tracknumber,ROLI_TRACKNUM)
addMidiReceive(tracknumber,PIANO_TRACKNUM)
else --do nothing it's an effect... or should we do something?
end
--set midiChStrip value for input type
reaper.TrackFX_SetParam(track,MIDICHSTRIP_SLOT_NUM,NS_SELECT_PARAM,nsIndex)
ultraschall.ShowLastErrorMessage()
end
GUI.name = "NS TEST"
GUI.x, GUI.y, GUI.w, GUI.h = 0, 0, 400, 200
GUI.anchor, GUI.corner = "mouse", "C"
GUI.New("nsNum", "Radio", 1, 192, 32, 80, 108, "", "KX8,DUAL,ROLI,NONE", "v", 4)
GUI.New("sldr_track", "Slider", 1, 32, 96, 128, "Track", 16,19, 16, 1, "h")
local elms = {}
GUI.CreateElms(elms)
function GUI.elms.nsNum:onmouseup()
setNotesource()
--ultraschall.print2(tostring(gui.Val("chk_opts")))
GUI.Slider.onmouseup(self)
end
GUI.Init()
GUI.Main()
|
|
|
03-29-2019, 09:28 AM
|
#422
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
The defaults parameter is in steps, starting fro 0, not the actual values used for min and max. You're telling it to default to step 16 when the slider only has steps 0, 1, 2, and 3.
Bad design on my part. It is in the docs though: https://github.com/jalovatt/Lokasenn...ki/2.00-Slider
|
|
|
03-29-2019, 10:33 AM
|
#423
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
Okay, I see how that works..... How about the radio button issue?
EDIT: Figured that out. Was referencing the wrong control in my mouseup method....
Last edited by woodslanding; 03-29-2019 at 10:54 AM.
|
|
|
03-29-2019, 10:56 AM
|
#424
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Oops, skipped right over that one.
You're overwriting the Radio element's onmouseup method but then calling the Slider class' original method inside, so the Radio isn't going to update properly.
|
|
|
03-29-2019, 11:00 AM
|
#425
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
I also noticed this:
Code:
local elms = {}
GUI.CreateElms(elms)
If you're using GUI.New you don't need to worry about this - CreateElms is an alternative syntax so you can create a bunch of elements from a table of parameters in one go: https://github.com/jalovatt/Lokasenn...d%20tables.lua
For what it's worth, v3 will be using the "table of parameters" approach for everything because it makes life way easier.
|
|
|
03-29-2019, 12:32 PM
|
#426
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
The Problem I'm having now is that I'm using the mouse up method to trigger my method, but I'm getting the previous value not the one that changed when I pressed the mouse... Not sure what I should do.
|
|
|
03-29-2019, 12:50 PM
|
#427
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Call GUI.Radio.onmouseup(self) before your code, so the value is updated before you check it.
|
|
|
03-29-2019, 03:39 PM
|
#428
|
Human being with feelings
Join Date: Dec 2015
Posts: 172
|
Hi, Lokasenna! Hi, guys!
I have some other questions! Please help me)
1) I want to resize and refresh GUI. I found this:
Code:
local __,x,y,w,h = gfx.dock(-1,0,0,0,0)
gfx.quit()
gfx.init(GUI.name, GUI.w, GUI.h, 0, x, y)
GUI.redraw_z[0] = true
It works.. but it makes script window focused, even if it wasn't focused before. I want to use it to display some information about selected item, it should update and resize to fit displayed info every time I click on any item (I did it in GUI.func), but don't want to make the window focused.
How to avoid focusing GUI while refreshing it?
Maybe there's a way to refresh (resize) GUI window without recreating it?
2) How to pass keystrokes from script GUI to Reaper itself? I want some codes work with script, and all others - pass to main window. I found out that in GUI.func I can make someting like this:
Code:
local char = gfx.getchar()
if char == 32 then reaper.Main_OnCommandEx(40044, 0,0) end -- space -> transport play
But how to pass other keys to main window just like main window keyboard focused?
Last edited by kartalex; 03-29-2019 at 03:47 PM.
|
|
|
03-29-2019, 04:01 PM
|
#429
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
1. There's no native way to do that - windows get focus when you create them. The JS extension has a bunch of extra window functions, so I think you can do it with that.
And no, we don't currently have a way to resize the window. Again, the JS extension might.
2. That's the only way to do it natively - specifying every key and the command to use. It's worth remembering that not everyone will use the same key mappings as you though.
|
|
|
04-01-2019, 07:14 AM
|
#430
|
Human being with feelings
Join Date: Mar 2019
Posts: 7
|
Hey all,
Firstly - Lokasenna thanks for the creation of this. Very helpful!
I'm just getting into the world of Reascript, making a very basic window to aid some live playback.
I'm trying to use the return from GetPlayState() to determine the background colour of the window.
So...
Question 1 - Is it possible to change the colour of the main window?
Question 2 - If not, I'm really struggling to get a frame to change colour based on the return state. See the code below.
if reaper.GetPlayState() == 1 then
reaper.ShowConsoleMsg("PLAYING")
GUI.elms.stop_bg.color = "red"
end
Am I barking up the wrong tree? I know we're entering the if statement as the Console is displaying the message I'd expect. The other option is to have two frames and change their Z layer value but again, this also doesn't seem to work which makes me think I'm doing something fundamental wrong.
Thanks in advance!
|
|
|
04-01-2019, 08:20 AM
|
#431
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Not at my Reaper machine right now but:
1. The window background is set by gfx.clear. Changing that should do it... you might need to close and reopen the window though.
Code:
gfx.clear = reaper.ColorToNative(R 0-255, G 0-255, B 0-255)
2. Any time you change something about an element's appearance, you also need to use GUI.redraw_z[elm.z] = true so it knows it needs a redraw. Many of the elements, like Frame in this case, will also need a call to their init method to redraw their internal buffers.
Code:
if reaper.GetPlayState() == 1 then
reaper.ShowConsoleMsg("PLAYING")
local elm = GUI.elms.stop_bg
elm.color = "red"
elm:init()
GUI.redraw_z[elm.z]
end
|
|
|
04-01-2019, 11:19 AM
|
#432
|
Human being with feelings
Join Date: Mar 2019
Posts: 7
|
Worked! Thanks Lokasenna.
|
|
|
04-04-2019, 08:35 AM
|
#433
|
Human being with feelings
Join Date: Mar 2019
Posts: 7
|
Me again! Anyone know if there's a way to centre align text in a label or frame?? Thanks!
|
|
|
04-04-2019, 09:35 AM
|
#434
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
I could have sworn I added that to the Label class right after Cockos updated gfx.drawstr to support alignment, but apparently not. Putting that on my to-do list.
In the meantime, you can center the label yourself any time after the window has been opened with GUI.center
Code:
-- center in another element
GUI.elms.myLabel.x = GUI.center(GUI.elms.myLabel, GUI.elms.otherElement)
-- arbitrary coordinates (xywh all need to be given even if you don't care about y - just put 0 or make up a number)
GUI.elms.myLabel.x, GUI.elms.myLabel.y = GUI.center(GUI.elms.myLabel, {x = 32, y = 48, w = 96, h = 16})
-- the window
GUI.elms.myLabel.x = GUI.center(GUI.elms.myLabel)
-- and don't forget:
GUI.elms.myLabel:redraw()
For the Frame... there isn't a good way. You can use its .pad property to adjust where the text ends up - it pads both sides, then wraps the text to fit the remaining space.
|
|
|
04-07-2019, 04:58 PM
|
#435
|
Human being with feelings
Join Date: Dec 2015
Posts: 172
|
Hi, Lokasenna! Hi, guys)
How to make my script (where Lokasenna's GUI is used) run in background, for when I hit Close button and reopen - it didn't restart, but kept working?
I have this in my script:
Code:
function Defer_Loop()
local char = gfx.getchar()
if char == 27 then MAIN_exit() end
if char == 32 then reaper.Main_OnCommandEx(40044, 0,0) end -- space -> transport play
if char ~= -1 then reaper.defer(Defer_Loop) else MAIN_exit() end -- stop on close
end
function MAIN_exit()
reaper.atexit()
gfx.quit()
end
--------- some code here
GUI.Init()
GUI.func=Defer_Loop()
GUI.Main()
But this doesn't keep it working in background ((
|
|
|
04-07-2019, 08:31 PM
|
#436
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
- You need to run your "keep it going in the background" loop separate from the GUI; when the window is closed, the GUI quits, so whatever you gave it for GUI.func will no longer be run.
- If your defer loop is what you're using for the background script, it won't work. gfx.getchar will always be -1 if there's no window open.
- FYI, running the script again won't reopen the window, it will kill the script and start it over again. If your GUI is just setting a bunch of parameters for the background script to use, this might be okay - you would just need to have it store the parameters in an ExtState or something and then read them when a new instance starts up.
- I don't think you actually can close the window and reopen it within the same script instance, actually, since the GUI does a bunch of stuff when you open the window and might crash if you tried to do it again.
I'm curious what you're trying to accomplish with this. Feel free to PM me if you need any help.
|
|
|
04-09-2019, 10:23 AM
|
#437
|
Human being with feelings
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
|
How can we add background images to jsfx, e.g. to filther?
|
|
|
04-09-2019, 11:08 AM
|
#438
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Not with my library - it only works with Lua scripts.
JSFX can load .png files - have a look at the Sonic Anomaly ones and see how they're doing it.
|
|
|
04-09-2019, 11:58 AM
|
#439
|
Human being with feelings
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,031
|
Thanks for the hint. Example SLAX.jsfx.
Writing at top.
PHP Code:
provides: slax_gfx/*
After sliders, adding a few .png like this, also defining as resource:
PHP Code:
filename:0,slax_gfx/bg.png
filename:1,slax_gfx/bigpot.png
filename:2,slax_gfx/prepot.png
filename:3,slax_gfx/needles.png
filename:4,slax_gfx/opt.png
filename:5,slax_gfx/optbut.png
resource:0,1,2,3,4,5
Defining background size.
Then grepping for gfx_r, gfx_g, gfx_b, gfx_a and gfx_blit for interesting ideas.
Resaving filther.jsfx as myfilther.jsfx and you can have your backgrounded filther or any jsfx, without an updated filther.jsfx overwriting your modifications. I can try some backgrounds plus 'Atari ST 8x16 System Font' on myfilther. Bri1 has created some great filther images already. This is how it can look then: https://github.com/JoepVanlier/JSFX/issues/5
Last edited by TonE; 04-09-2019 at 01:20 PM.
|
|
|
04-15-2019, 01:57 AM
|
#440
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
How is V3 coming along?
I'm getting very close to having all my backend stuff working properly, and back to considering gui.
How is V3 coming? Would it be ready for beta testing anytime soon? Or am I better off diving into trying to write components for v2?
|
|
|
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 12:25 AM.
|