What's new

Liine Lemur (for Android) - creating objects on-the-fly

quickbrownf0x

New Member
I'm wondering if it's possible to dynamically create and render an object, like a Monitor or Container by triggering a (global) function/bit of script. Like so;

decl contain_obj = new Container();// create the object
setattribute(contain_obj, 'rect', {0,0,640,480}); // set its dimensions and placement
show(contain_obj, 1); // render on screen.

Or maybe create a function;

function createContainer(id, positions, dimensions)
{
decl contain_obj = new Container(id);
setattribute(contain_obj, 'rect', {positions[0], positions[1], dimensions[0], dimensions[1]});

show(contain_obj, 1);
}

And then whenever I need it I can just go;

createContainer('oohlookatthisshinynewcontainer', {0,0}, {1280, 960});

...tie that sucker to a button, you know - something like that....

Liine's own documentation's a bit shit. Can't find anything about it. Does anyone know, or has anyone tried this? Or am I just being too much of nerd and do I have to accept the fact that my fancy Lemur UI won't be as flexible and dynamic as I would like it to be? Because (as far as I know) the alternative is to hard-code a ton of stuff, including things like patch articulations and their labels. Which would suck. I mean, that's just stupid.

Cheers,
Dj.
 

WindcryMusic

Lemurite
I don’t think it is possible to dynamically create objects in Lemur (sure would be nice if one could). But you don’t have to hardcode things like the text on labels ... that at least can be set via the object attributes. I do so all over the place in my template, along with hiding and showing buttons as needed.

If you really need more control, I suppose you could use the Canvas object to dynamically draw your own buttons as needed. I’m not sure if you can get them quite as pretty as the built-in button objects, but it does give you some flexibility. I use the Canvas object in my own template to create and dynamically color and label a keyboard graphic, as seen here:

 

pmcrockett

Senior Member
One other thing that can help get around the fact that you can't dynamically create objects is that you can, to some degree, dynamically address objects from within the code. The functions findobject(), getfirst(), getnext(), getobject(), and getparent() allow you to navigate the objects' tree structure without necessarily knowing the objects' specific names. See pgs. 128-129 of the manual for the (limited) documentation on these functions.

You can, for example, have code that will iterate through all objects in a folder whose names fit a certain pattern. Below is some code grabbed from one of my projects that iterates through 99 articulation buttons named ArtCell01 through ArtCell99, each of which is an identical object. I still needed the 99 objects to already exist, but I just had to copy/paste them in the editor. The pasted duplicates were auto-named correctly, and the code automatically found them.

Code:
decl curCell = Editor.ArtCellCon.ArtCell01;
while (getattribute(curCell, 'name') <= 'ArtCell99')
{
    //code that operates on the button goes here
    curCell = getnext(curCell);
}
As Windcry mentioned, you can label, position, and hide the buttons from within the code, so you can use this iteration to set up the buttons however you want and hide the ones you're not currently using.

If you want to do something like this but need better text parsing abilities for the name comparisons, I posted a string to vector text parser in some thread a while back that I can dig up for you.
 
Last edited:

WindcryMusic

Lemurite
One other thing that can help get around the fact that you can't dynamically create objects is that you can, to some degree, dynamically address objects from within the code. The functions findobject(), getfirst(), getnext(), getobject(), and getparent() allow you to navigate the objects' tree structure without necessarily knowing the objects' specific names. See pgs. 128-129 of the manual for the (limited) documentation on these functions.
Yep, this is good to do too if you don't already (my Lemur template is highly dependent on such things).

One thing that tripped me up for a while was not understanding that there are different API methods for getting the values of expressions as opposed to screen objects. (I do much of both.) Look at getexpression(), as opposed to findobject() and getattribute(). And don't overlook the findchild() call that was added in the most recent update, as it is a handy shortcut.

If you want to do something like this but need better text parsing abilities for the name comparisons, I posted a string to vector text parser in some thread a while back that I can dig up for you.
As an aside, I did try using that text parser code of yours (which is a pretty impressive hack) at one point. For a few simple parses it works perfectly, but when I gave it some real work to do it crashed Lemur badly after the first several times it ran ... I think it ran Lemur out of stack space or something like that. So I'd have to recommend some caution on that one.
 

pmcrockett

Senior Member
As an aside, I did try using that text parser code of yours (which is a pretty impressive hack) at one point. For a few simple parses it works perfectly, but when I gave it some real work to do it crashed Lemur badly after the first several times it ran ... I think it ran Lemur out of stack space or something like that. So I'd have to recommend some caution on that one.
Good catch. I didn't thoroughly stress test the parser at the time, but I just dipped into the project again and it looks like Lemur cuts loops short and/or doesn't run them at all if they're too long, so my guess is that either the parser is encountering strings it can't match and Lemur is freaking out because the function's built-in failsafe loop limit is too high or that generally running the function embedded too deep in other code might be hitting the loop limit. If I can duplicate/fix things, I'll bump the other thread with an update; thanks for bringing this to my attention.
 

WindcryMusic

Lemurite
Cool, thanks guys. That makes sense. @WindcryMusic/David that auto key mapping thing looks pretty nifty. Same goes for this;


Really cool. Care to share that project file? lol
Hehe. The specific project probably wouldn’t help you, as it is pretty specific to my configuration including use of ArtZID v2, but I have had the thought to make a YouTube video or two to show and discuss some of the programming behind it. Maybe that would interest you?

By the way, that touch-driven UI shown in my 2nd IG post is still in there, but I hardly ever have to select anything manually anymore like that, because I now use Osculator along with some additional Lemur programming to have articulation pages selected automatically when I change Logic tracks. (Implementation hint: I have a container full of expressions like “t1”, “t2”, etc., each containing a vector with one of the track names in my Logic template, along with info on which articulation tab and page to bring up, and then I use some of that container iteration coding mentioned earlier in this thread to walk through until I find a match for the newly selected track in Logic. Works a treat, if I may say so myself.)
 
Last edited:
OP
quickbrownf0x

quickbrownf0x

New Member
Hehe. The specific project probably wouldn’t help you, as it is pretty specific to my configuration including use of ArtZID v2, but I have had the thought to make a YouTube video or two to show and discuss some of the programming behind it. Maybe that would interest you?
I'd totally understand if you're too busy, but yeah - that would be awesome. Odd how little information's out there on this topic. Not what I expected. A few support pages and a handful of dudes on Youtube - that's pretty much it.

...I now use Osculator along with some additional Lemur programming to have articulation pages selected automatically when I change Logic tracks. (Implementation hint...)
Sweet, I'll check that out. Thanks everybody.
 
Last edited:

WindcryMusic

Lemurite
I'd totally understand if you're too busy, but yeah - that would be awesome. Odd how little information's out there on this topic. Not what I expected. A few support pages and a handful of dudes on Youtube - that's pretty much it.
Cool. I’d been planning on this last fall, but had sort of let the idea slide because of various issues, including the ongoing questions about whether Lemur is still going to be supported going forward. But this makes me think that I should perhaps still do so.

About those ongoing support questions, I personally find Lemur essential enough to my workflow that I would be more than willing to pay again for a “Lemur 2.0” new version that updates said support to the latest versions of iOS, fixes the main bugs and hopefully adds at least a few new features, if that is what Liine would need to make continued support of the product viable. Certainly that’s what many other iOS app makers do to sustain their businesses.
 
OP
quickbrownf0x

quickbrownf0x

New Member
Nice! Yeah, same here.

Hey, does anybody know how to go about doing this in the Project Logical Editor (by any chance?);

- select and toggle subfolder "X" where the parent folder is "Y".

I'm about to poke my eyes out with a rusty fork. :cautious:
 
Top Bottom