Cabbage Logo
Back to Cabbage Site

New proposal for modular GUI, part 2

How about the actual radiogroup() cabbage declaration (in this case 99)? Does this get accounted for yet, and if so how?

That’s cool, but as we start to use modular code, won’t that be counterproductive? Honestly I’d be more interested in a way to export multiple files at once in a way that keeps shared modules/files as actually shared. I understand how this could be more difficult tho.

Wow, this is all looking really cool! Obviously I’m still rooting for those macro expansions… :innocent: I definitely plan on sharing what I’ve been working on once it’s done. And I think you’ve convinced me to give up on maintaining C1 compatibility at this point :wink:

Is that really the full example? I feel like something is missing… I get the idea of the cabbagecode section tho. That’s neat!

Yes. As the check boxes belong to the plant, their radio ids are local to that plant.

It’s only a side effect I thought was worth mentioning. I’d need to add a way of actually exporting the full text files if anyone was interested. [quote=“t_grey, post:14, topic:785”]
Wow, this is all looking really cool! Obviously I’m still rooting for those macro expansions…
[/quote]

I think even now there are workarounds for this, i.e., making sure you give your plants enough utility UDOs to control how they look and behave! [quote=“t_grey, post:14, topic:785”]
Is that really the full example? I feel like something is missing… I get the idea of the cabbagecode section tho. That’s neat!
[/quote]

Yes, that’s really the full thing. I simply create the plant by running a simple JS for loop which outputs
lines of Cabbage code using Cabbage.print(). The code it generates is then used as the Cabbage code for that plant. I’ve been meaning to add a way of progamatically creating GUIs for some time. Javacript is nice because JUCE comes with its own simple JS engine.

I don’t see where there’s any handling of the stop/random/clear buttons or the tempo… are there UDOs that went with it? That’s what has me confused… I think I understand the drawing part, just expect to see more.

I have to politely but enthusiastically disagree, but I’ll admit it might be because you’re already aware of a good easy solution that I’m not. Having the ability to change them is great through internal methods, but this (at least as far as I know) doesn’t provide any way to have an unknown number of plant instances themed with common color settings unique to the instrument/instance. Plus, the larger and more complex an instrument got, the more work would be required in the initialization/skinning of the plugin, right?

For example, if I write a bunch of exported plants, it should be fairly simple to skin them all in a blue theme in one instrument, and grey in another. With macros you could just include a different set of color defines prior to including the plants files to achieve this, but without them I’m concerned that you would have to iterate through each plant unique to the instrument, sending them identchannel messages just to get an initial color set. Having the methods attached helps ease that pain, sure… but honestly, it feels like a bit of a mess to me.

Another, perhaps better example; I’m hoping to be able to change a single shared include file with some color definitions, and have it change the look of an entire group of instruments at a time without any other work within the instruments. I think the same problem/principle applies.

But again, it’s very possible I’m just missing the obvious answer to the problem.

I see your point. It’s a valid one. I don’t like macro use here because they are global, but I agree that some quick and efficient way of passing theme data to imported plants is probably a must. Let me think about it.

Oh btw, yes, there were UDOs controlling the widgets. I forgot I only posted the script part.

I see your point here. But as soon as you hard code a macro into a plant, then you need the person to define that macros in your main .csd file. If we just consider the CabbageCode section of an import xml file. You’d like to be able to do this:

<cabbagecode>
	image bounds(0, 0, 160, 50) colour("red") $image_attribs {
	button bounds(10, 40, 30, 30) channel("killerWidgets_button1") radiogroup(99), text(""), $button_attribs
	button bounds(40, 40, 30, 30) channel("killerWidgets_button2") radiogroup(99), text(""), $button_attribs
	button bounds(70, 40, 30, 30) channel("killerWidgets_button3") radiogroup(99), text(""), $button_attribs
	button bounds(100, 40, 30, 30) channel("killerWidgets_button4") radiogroup(99), text(""), $button_attribs, value(1)
	}
</cabbagecode>

In this case you use two different macros which need to be defined in your Cabbage section in the parent .csd. I guess this is fine, but I’m afraid it will get messy. Let me take a look. It would mean that others hoping to use your abstractions will have to do some work first to get the macros set up.

This sounds like a stylesheet. I have considered implemented custom global style sheets in the past. Might be worth looking at again.

A missing macro define in the cabbage section doesn’t currently fail compilation, it expands to nothing… here it should be no different. If the macro is defined as “colour(red)” rather than “red”, then the missing macro wouldn’t have a significant negative affect the widget, but would just leave all widgets in their default color states. I don’t see this as a problem at all, it’s carrying the expected behavior into the included abstraction! And IMHO this still allows very simple and easy flexibility for the author.

Perhaps… but again, other than being the default colors there’s nothing really REQUIRING it if it’s designed somewhat logically. But even so, I was already considering/expecting that many of my abstractions might have a slightly more specialized version for my own instruments with the theme macros etc, versus a more public “general purpose” widget abstraction with the extra stuff stripped out.

Hrm… very interesting. I assume this would include the ability to declare arbitrary “classes” for widget types, or would it be assumed that all widgets would inherit a monolithic style? The former could work for my intentions… but I still see this as ending up with the same “problem”. In the absence of the style definitions, you’d be back to defaults.

I don’t know. Sounds like a lot of work to end up with what sounds like the same basic functionality to me. :stuck_out_tongue:

That’s a good approach.Regarding the stylesheet option, something like:

<cabbagestyle>
	image: colour("red") 
	button: colour("pink"), text("Button")
	hslider: colour(green"), range(0, 1, 1, 1, 1)
	checkbox: value(1), text("Mute"), colour:0("red)
</cabbagestyle>

Which can be imported when creating your main form:

<Cabbage>
form size(400, 300), import("darkTheme.xml")
hslider ...

All widgets would adhere to this monolithic theme when created. But it doesn’t give as much scope as macros does it? The problem is when you import two plants that have the same macro names. In some cases this is ideal, in others it will create problems and confusion.

Btw, Csound 7 will support namespaces which should make this easy to modify later. At present I think it’s planned to use them for UDOs. So one could give all UDOs a namespace, so a UDO called phasor in your personal collection might be called like:

aSignal myUDOs::phasor 10

That would mean we don’t have to prepend a unique ID to each UDO name which is a little ugly.

I think that functionally, this stylesheet idea would be no different to me than having the unexpanded macros there. All widgets end up the same with a base style. Definitely cool and useful in certain situations, but doesn’t entirely fill my specific needs. I could probably set a baseline of some sort (particularly plants and maybe fonts), but I would still need macros or have to keep track of widget instances and set them manually via a UDO/method to end up with different classes of certain widgets. For example, having different colored knobs based on function (pan,drywet,effect,filter,gain)

That’s an implicit issue with using macros in just about any situation or language, isn’t it? Ideally macros wouldn’t be defined in the included abstraction files anyway… but really, as usual, it should be up to the user to not do something silly with their macros and definitions. You can’t protect entirely from the user doing something dumb or counterproductive… I’m proof of that :grinning:

Tho if you want to go overboard… I could always request ifdef ifndef and undef for the cabbage section… those could definitely help that situation :innocent:

I saw some of the discussion about that, it looks very interesting and useful.

I just updated the OSX installer for Cabbage 2, see beta releases page. This version supports the new import() system. It also includes a few simple example files in the Instructional folder (customPlantImport and GridSeqneucerImport) that show how to import plants from xml files. It’s still quite raw so please don’t expect everything to just magically work out of the box, it’s relatively untested! For now you can only import one plant. I will remove this restriction shortly. I just don’t want to give you guys too much rope!

You can however import as many macro files as you wish, i.e., import("macro1.inc", "macro2.inc", etc)

Oh and macros should also work across imported plants.

1 Like

Sounds awesome! Looking forward to trying it out. Any chance of a lite installer (particularly OSX) getting added to the mix? :innocent:

Just curious, do you mean only import one type for multiple instances, or only one instance of any type at a time?

You can only import one plant xml file at present but you can instantiate as many of that plant as you wish.

Cool, that’s what I figured but wanted to be sure! That means once I get that far I’ll try creating some multi-instance widgets to test with first, already have a good one picked out for it :slight_smile:

But first, I’m having some difficulties importing a “simple macro” include file, such as the ones I’m using for color/style definitions etc. I didn’t see anything in the examples that helped me and I tried a few random ways with no success, so I have a few questions about that:

I’ve tried:
#include “includes/tg_colors.inc.csd”
#import(“includes/tg_colors.inc.csd”)
import(“includes/tg_colors.inc.csd”)
and having the import on the form declare like so, no luck yet.
form caption("GUI Test") size(380,294), pluginID("tgui"), import("includes/tg_colors.inc.csd"), $ROOT

  • Does a simple macro file need to be structured as xml too with a cabbage section?

  • Does it have any filename (purely naming here, ignoring actual content) requirements that distinguish the import behavior (such as .xml vs .inc vs .csd) that defines or alters how cabbage will treat it?

  • Should this be done as part of the form declaration like a widget import, or as a standalone cabbage section import statement, or is this somehow done differently?

  • Assuming the import is supposed to be done on the form declaration line, would the $ROOT usage in the above example be valid if ROOT had just been defined in the file that was just imported on that same line?

Unrelated to that, does cabbagelite not have anywhere to check the current running version? I ran into issues before I realized this version installed over cabbage1, not cabbage2… so I was puzzled by the wrong version message for a little bit in the full gui version.

Anyways… once I have simple imports working, I’ll start converting some widgets into importable versions to try out and give some feedback there. Very excited to start trying that out!

edit: just FYI, a bunch of things appear to be working as expected in c2, but not in c2lite. the “radiobutton” vs “radiobutton2” define order thing is still an issue. Not a big deal to me, just pointing out since it’s fixed in the full version :slight_smile: Same goes for the instrument title not appearing when launched from sublime (aka via command line options/arguments), instead just getting “CabbageLite”. Both of these issues were discussed here, if you need more info: Cabbage2lite pre-testing: 1

It also seems like my plant woes may be specific to c2lite. I found that if I copied your new examples (along with the .xml files) to a new folder and tried to run them from there rather than from the builtin examples dir, it quietly fails to import and I get an empty screen. But if I switch my build system to the full c2, the imports work just fine.

This makes me wonder if the c2lite didn’t get rebuilt before making the package? But without a version #, there’s no way to be sure :stuck_out_tongue_winking_eye:

Yup, that’ll be what happened… let me cook you up a fresh version…

Can you try again? New version just in.

That’s the way to do it. I’ve put an example into the Instructional folder called macroImport.csd. See how that works.

No.

No, it’s treated as plain text. All that’s happening is a textual expansion.

I probably answered that one above, it should be part of the form declaration.

Hmm, my initial reaction is no, but it could be worth trying! We could be lucky :joy:

Sorry about that, I should say it’s probably best to rename Cabbage 1 first! I will add an about dialog to CL to inform users of the version number. It will probably be the same as the main Cabbage just to keep things simple.

I get a 404 on the OSX installer now over here: Latest beta packages available here (updated links)

Was that the installer I should be trying?

And sorry, I actually answered a few of my own questions once I realized c2lite wasn’t updated and the new c2 was where c1 used to be. I had tried everything and nothing was working, but once finally actually testing in the new version of full c2 I was able to stumble through just fine.

Actually, my test last night with it seemed to work!

That’s fine, and probably the best bet. Just having somewhere to look tho would be useful, otherwise there’s no way to report bug against specific version, or make sure I’m actually running the updated one I meant to be :wink:

Gees, sorry about that. I just updated the link. It was a long day at work. Try again and let me know. Relative paths in the import() stuff seem to work fine for me here. Hopefully it’s the same for you!

No worries at all. Installed and working… I’m in business now, thanks a bunch!

Relative paths are indeed working, and the $ROOT macro DOES expand when it’s imported on the same line, confirmed. :slight_smile:

I’ll play with this for a bit today and make some importable widgets. I’ll probably start a new thread with any feedback and problems encountered later tonight.