Home Forums General Programming IncDec Selected Modulator ?

This topic contains 44 replies, has 5 voices, and was last updated by  human fly 3 months, 1 week ago.

Viewing 20 posts - 1 through 20 (of 45 total)
  • Author
  • #73428

    human fly

    already, i seem to have forgotten/don’t know how this might be done …

    i want to use one method for several ‘click’ items (labels) which will
    identify which has been clicked, in order to determine which modulator
    must be incremented/decremented.(this was explained to me by goodweather
    some time ago, i’m just catching up with this now..)

    this fails/gives a Callback error:

    function decSelected()
    -- increment selected modulator
    local p1 =panel:getModulatorByName("pcm1_pt1p1")
    local p2 =panel:getModulatorByName("pcm1_pt1p2")
    local p3 =panel:getModulatorByName("pcm1_pt1p3")
    local p4 =panel:getModulatorByName("pcm1_pt1p4")
    local dec1 =panel:getModulatorByName("pcmDec_pt1p1")
    local dec2 =panel:getModulatorByName("pcmDec_pt1p2")
    local dec3 =panel:getModulatorByName("pcmDec_pt1p3")
    local dec4 =panel:getModulatorByName("pcmDec_pt1p4")
    -- local dec = nil
    for i=1,4 do
    	local dec= L(panel:getComponent("pcmDec_pt1p"..i))
    	console(String("selected is: "..dec))

    i did getModulatorByName() as well.
    error is:

    At line [-1]: [C]
    What: C
    Namewhat: global
    Name: L
    Error message: No matching overload found, candidates:
    std::string L(String const&)

    try maybe this

    for i=1,4 do
    local dec= panel:getComponent(“pcmDec_pt1p”..i)
    console(String(“selected is: “..dec))

    not in front of my workstation now so can’t check it ATM.


    human fly

    lol well it definitely doesn’t like the console command
    inside the ‘for’ agrument ! > Ctrlr crash.

    so putting that after that bit returns error:
    Error message: [string "decSelected"]:19: attempt to concatenate local 'dec' (a nil value)

    and if i put the console thing as
    console(String("selected is: "..(tostring(dec))))
    it returns
    LUA>> selected is: nil

    panel-ito below >

    You must be logged in to view attached files.

    human fly

    well this didn’t work either; how to get mouseclick on
    a label… maybe i should try something else…

    	for i=1,4 do
    	local idec=L(panel:getComponent("pcmDec_pt1p"..i):getProperty("componentLuaMouseDown"))
    		if idec==true then
    			console(String("selected is: "..idec))

    no return at all 🙁

    myChangeCombo = function(--[[ CtrlrModulator --]] mod, --[[ number --]] value, --[[ number --]] source)
        local NAME=mod:getProperty("name") 
        -- or Name= L(mod:getName())
        local endChar = string.sub(NAME,-1)
        local begChar3 = string.sub(NAME,0,3)
        --console(String("Name = : \""..NAME.."\""))
        --console(String("endChar = : \""..endChar.."\""))
        --console(String("begChar3 = : \""..begChar3.."\""))
        local comboName="pcm1_p"..endChar
        local val = panel:getModulatorByName(comboName):getValue()
        local min=panel:getModulatorByName(comboName):getProperty("modulatorMin")
        local max=panel:getModulatorByName(comboName):getProperty("modulatorMax")
        if begChar3 == "inc" then --  increment value
            if  val == max then --(this is the last element)
                ch=0 -- or ch = max
                ch = val + 1
        else -- decrement value
            if  val == min then --(this is the first element)
                ch = val - 1
    end --function

    This is one solution (while trying to keep everything in one function), but it’s a different approach entirely 🙂

    You must be logged in to view attached files.

    human fly

    wow that’s excellent – solves the whole problem for methods
    common to several controls and modulators. thanks for the

    is NAME in caps for emphasis on what this method is about?
    (we read that caps are not necessarily desirable in variable names..)

    and so: NAME,-1 presumably is the ‘whole’ character count minus 1.
    could be: -2,2 ? if you wanted to specify the last 2 characters?
    -3,3? etc. ?

    or rather, string.sub(NAME,0,3) specifies start point and the number of items.
    ok, new to me as well ( although there is something similar in synthedit with
    the David Haupt modules, never had much use for it there beyond demo-ing it)

    does ‘ch’ stand for ‘change’? can’t think of another reason for the

    great method !


    I suppose I shouldn’t have a variable in all caps like that!

    ch – I don’t know why I chose that – maybe change value -> hence ch, but I would usually give that a more meaningful name I suppose!

    I always refer to this page for string manipulation.


    human fly

    string.sub(s, i [, j])
    s:sub(i [,j])

    Return a substring of the string passed. The substring starts at i. If the third argument j is not given, the substring will end at the end of the string. If the third argument is given, the substring ends at and includes j.

    > = string.sub(“Hello Lua user”, 7) — from character 7 including 7 until the end
    Lua user
    > = string.sub(“Hello Lua user”, 7, 9) — from character 7 until and including 9
    > = string.sub(“Hello Lua user”, -8) — 8 from the end until the end
    Lua user
    > = string.sub(“Hello Lua user”, -8, 9) — 8 from the end until 9 from the start
    > = string.sub(“Hello Lua user”, -8, -6) — 8 from the end until 6 from the end


    human fly

    now taking a closer look at that gsub thing too ..

    string.gsub(s, pattern, replace [, n])
    s:gsub(pattern, replace [,n])

    This is a very powerful function and can be used in multiple ways. Used simply it can replace all instances of the pattern provided with the replacement. A pair of values is returned, the modified string and the number of substitutions made. The optional fourth argument n can be used to limit the number of substitutions made:

    > = string.gsub(“Hello banana”, “banana”, “Lua user”)
    Hello Lua user 1
    > = string.gsub(“banana”, “a”, “A”, 2) — limit substitutions made to 2
    bAnAna 2


    human fly

    i see you have ‘disable combos on edit’ ticked.
    how does this help? i supposed i always have a bit of
    difficulty moving them, because they expand every time
    i want to move them. is that all? i notice they go dark
    when it’s in Panel Edit.

    interesting Lua wiki page on patterns, too.
    having noticed ‘%a+’ – which i didn’t understand for selecting
    a word – i thought it could cast some light of use of ‘%’ in
    string.format expression.


    currently editing your method a bit for my purposes.
    really like this – can pop it straight into the D-110
    panel. if you consider how useful something like this
    can be in a multi-timbral instrument panel to avoid
    having multiples of the same methods …

    this is definitely the way forwards! >

        local NAME=mod:getProperty("name")
        local endChar = string.sub(NAME,-1)
        local begChar3 = string.sub(NAME,0,3)
        local comboName="pcm1_pt1p"..endChar

    i supposed i always have a bit of
    difficulty moving them, because they expand every time
    i want to move them


    this is definitely the way forwards

    ..I’m glad it has helped. Knowing the name of the Modulator that calls a function and then being able to perform a task based on the Modulator’s name can be very useful.

    Patterns have a few pre-defined classes, use them as “%x”, where “x” is the letter identifying the class: …. Must be similar to string.format() syntax, but not the same. One function is searching strings, the other formatting.

    string.match("foo 123 bar", '%d%d%d') -- %d matches a digit

    but the string.format("%s",20) is using the same syntax as printf format string found in C/C++ and other languages


    human fly

    !now: …

    very odd:
    i amended your version of the panel+method with my original
    naming for the combos – though kept the inc/dec with same
    name, and it works. – i note that you replaced the label objects
    with image buttons.

    so then, i copy over the method into my big panel, where i needed
    to edit the names of those combos anyway, but *kept* the click-on
    label arrows (to see if it still works that way).

    now i get a callback error at #8 with the ‘sub’ not being able
    to find (NAME,0,3) (which confuses me a little: oh… i think
    i’ve sussed it actually, my bad possibly: 0,3 is counting FOUR
    characters?? duh… 0,1,2,3 … maybe if i try NAME,0,2 or something)

    nb: to jolly things up, in my panel each pcm1p(n) combo is linked
    to its counterpart pcm2(n) combo with Link to Modulator property.
    but i renamed them all so even that should cause a problem.

    this is an imperfect solution i found to the D-110 feature
    -with the parameter called ‘Wave/Bank’-
    where ‘PCM Bank 1/2 Select’ corresponds to ‘sqr/saw Select’ :

    the parameter has values 0,1,2,3 :
    on the synth/S side it goes sqr,saw,sqr,saw and on the PCM/P side,
    it goes pcm1,pcm1,pcm2,pcm2 … so i had to bodge up something
    that represented this. and of course pcm1 and 2 have to synced/linked,
    so that switching banks keeps the pcm number. these disappear when
    synth/S is selected for the ‘Structure’ algorithm. (which is a bit
    different on JV)

    so i need to try to ‘sub’ characters again there for some reason.


    human fly

    no sorry talking rubbish again:
    it’s line #8: (NAME,-1), and that should be working.
    i’ll have to try again later. day commences.


    Paul Scheidt

    I’ve taken several cracks at this, and as best I as I can tell, the Ctrlr methods to get the modulator name return the data type “userdata” and not the data type “string”.

    From the LUA 5.1 Reference Manual:

    The type userdata is provided to allow arbitrary C data to be stored in Lua variables. This type corresponds to a block of raw memory and has no pre-defined operations in Lua, except assignment and identity test. However, by using metatables, the programmer can define operations for userdata values (see §2.8). Userdata values cannot be created or modified in Lua, only through the C API. This guarantees the integrity of data owned by the host program.

    More specifically on your code:

        local NAME=mod:getProperty("name")
        local endChar = string.sub(NAME,-1)

    First line sets value NAME to be the userdata type. The second line throws an error because you’re trying to run a string function on a userdata value.

    As it says there, you can’t modify userdata values in LUA. Using the modulator’s VSTIndex seems to be the only way to identify which modulator called a function.

    I’m hoping you find a solution, but that’s been my experience so far. Maybe there’s a more advanced LUA trick to translate the userdata to a string?


    human fly

    here’s the panel again with the combos repeated ‘in context’,
    ie: there are 2 linked combos for each, with another combo/switch
    controlling which is selected. have provided the inc/dec arrows,
    as regular buttons(closest to the combo setup), and as labels
    (on the right) – note that after toggling and running dynamic/static
    for the first pair, they’ve taken on a ‘value’ property that the
    others don’t yet have. probably some renaming to be done here.
    just getting it to you on seeing your post, hadn’t finished it.

    (this is the D-110 synth/pcm select via Structure select, per
    partial, with the selection of pcm1/pcm2 lists i mentioned
    earlier. maybe have a look at how those are selected first)

    see bpanelz (it has one resource image included for Structure)

    You must be logged in to view attached files.

    Hi Paul,

    I think:

    local NAME=mod:getProperty("name")
        local endChar = string.sub(NAME,-1)

    is working; it returns the name of the modulator,

    However, by using metatables, the programmer can define operations for userdata values

    maybe the function getProperty() does this?

    But Human Fly maybe was possibly trying to run mod:getProperty on a callback function from a mousedown function on a uiLabel object, but that callback function doesn’t return the “name” Modulator variable. The first parameter is “comp” not “mod” anyway – the clue must be in the name “comp” – it only returns type “component”: Here are some values I discovered it returns:

    myMethod = function(--[[ CtrlrComponent --]] comp, --[[ MouseEvent --]] event)

    It might be possible to put arbitrary values into the field uiLabelInputAllowedChars and use them to identify which uiLabel triggered a function call on mouseDown events- maybe a bit of a hack!



    Hi Human Fly,

    Your latest panel isn’t working because of this reason: 🙂

    But Human Fly maybe was possibly trying to run mod:getProperty on a callback function from a mousedown function on a uiLabel object, but that callback function doesn’t return the “name” Modulator variable

    ..except now you are trying to return mod:getProperty from a mousedown callback from a uiButton.


    human fly

    yes, definitely my fault: i wanted to check out if it
    could be done with a click on a label – and then with
    a click on a button. apparently it is not the same
    thing, which i found reasonable with a uiLabel since
    they are not usually ‘dynamic’, nor have a VST Index.

    i thought it might be more possible with a uiButton,
    though. – i tend not to make/use images, where possible
    now, since Ctrlr has pretty adequate graphic capabilities.

    several other reasons:
    1/ i’ve spent enough time making stuff in knobman/skinman
    2/ want to avoid external resource files as much as possible
    (and explore Ctrlr’s graphic capabilities)
    3/ can edit Ctrlr graphic colours much more quickly and easily
    4/ end file size (minor issue with tiny graphics like this)

    can of course relent on this, for the sake of a great method 🙂
    and i already have a few graphics in there.
    (imagine suddenly wanting to reskin an entire panel/plugin..)

    it took a -short- moment to realise you’d swapped my labels
    for images you had made 😉 – note that all my LEDs in my main
    project are uiLabels using a colour property for on/off state.
    that’s because Ctrlr has no native ‘LED’, and i usually do
    plain flat led graphics anyway.

    did you use knobman to make those pngs? that’s another thing:
    knobman is not great at doing symbols to scale sometimes. you
    know it can do transparent ‘solid’/clickable with a transparency
    (alpha) of 1? i’ve used that a lot. (useful if you want to add
    a ‘glow’ as well)

    ps: roaming folders – would be nice if those ID names appended
    the file name ! would make it easier to purge the folder of
    unused/empty folders periodically. also, i think Ctrlr scans
    all of those folders on startup, so it slows down after a
    while. need to make request/github post for that.

    ok, so it’s back to uiImageButton then !
    (since regular button does not appear to want to do it?)


    human fly

    btw where are those references to ‘comp’, ‘mod’ ?
    couldn’t find it;


    human fly

    reason for all this, of course, is that the Ctrlr inc/dec
    uiSlider ‘style’ does not allow much editing, and if you
    size it right down (i needed that space, had to be tiny)
    the ‘-‘ becomes a dot, and the ‘+’ doesn’t look great
    either. also cannot see anything to determine rounded
    angle amount, nor how to change the button symbol colour.

    it does have some advantages, like hold down to scroll
    (i think?)
    maybe you’ve noticed that Link Modulators came up on wrong
    selection ie: orange for some of those combos. it has been
    a recurrent issue i had to resolve by forcing the view on
    startup, since it seems to do it irrespective of combo value.
    can’t work out why this is.

Viewing 20 posts - 1 through 20 (of 45 total)

You must be logged in to reply to this topic.

Comments are closed.