[Bf-taskforce25] AutoLayout and RNA API

vekoon vekoon at gmail.com
Thu Jan 29 20:00:58 CET 2009


Hi,
I've started implementing autolayout for collections and I stumbled upon 
a couple of issues (note that I gave the name "AutoLayout" to the 
automatic ui system so I can refer to it more easily). Note also that 
this is just a demo implementation or proof of concept that is, to show 
how groups could be used to automatize UI and the entire implementation 
code for AutoLayout is probably below 500 lines of code and thus can be 
easily tweaked or even entirely rewritten.

A first problem of the current system is that it is assumed that every 
group is uniquely laid out, which means that you can't display the same 
group more than once without having some weirdness. This makes sense 
generally (why would you lay out Object -> Transform twice, for 
instance?) but in more specific contexts it actually is a limitation and 
these contexts are collection properties where the same type/struct can 
be used more than once and thus its properties will be displayed more 
than once (and so the groups for those properties).
This is actually a good thing as this will force me to clean up the code 
and separate right from the beginning the caching part which keeps track 
of groups/properties and the part that instead keeps track of local 
space settings (like which groups are expanded or collapsed etc.) which 
means it should be easier then to move the caching part to a more global 
location (like WM) so that it can be reused across all the editors.

Now, an issue here is that when you keep these local space settings you 
kind of need to release them at a certain point when the context changes 
but this could be annoying for the user if done the wrong way. For 
instance let's say you have Cube selected and you collapse its subsurf 
modifier group settings, now you select Cube.001; in this case you can 
easily check if Cube.001 has a subsurf modifier group as well and in 
that case you keep it at a collapsed state. Now consider that you 
collapse the group for the array modifier on Cube.001 then select back 
Cube and Cube has 2 array modifiers, what to do? Collapse both of them? 
Just the first one? Or none? And in the latter case what happens if you 
select Cube.001 back? Of course you can't keep these settings 
per-object, so you need to decide arbitrarily when to get rid of or keep 
them. I know modifiers in this case have an RNA property, "expanded", 
that is used to keep track of expansion state in the UI, but I think 
this is a really dirty trick as it keeps RNA data UI-aware which should 
be always avoided in my opinion, especially in this circumstance where 
it is not needed thanks to groups. Also using properties for this type 
of UI information would make it not possible to manage automatically 
because you can't really base automation on properties name, can you?

Another issue is: when you iterate over properties for a certain struct 
it always returns automatically the properties for the base struct it 
inherits from. For instance again with the example for modifiers, when 
you iterate over SubsurfModifier you get also "name", "type" ecc that 
belong to "Modifier" which is good in most cases but sometimes you have 
to distinguish between own and inherited properties. For instance when I 
create the cache I was talking of before, I list all the properties in 
their relative connection to groups. Now, in order for this list to be 
consistent I need to list only those properties that strictly belong to 
a certain struct (and thus to a certain root group), but as of now I 
don't think there's a way for doing so. I think this should be added to 
the API and this would solve a couple issues that as of now makes 
AutoLayout work bad for collections.
Let me know what you think about this.

Also, something I'd like to clarify for my own good (and not just mine) 
is if there are the bases for groups to likely be integrated into 
current RNA system. Although the code for AutoLayout is definitively not 
ready for inclusion or even review the API for RNA groups is pretty much 
clean and I think ready for review and possible inclusion.
The reason I'm asking this is simply practical. If groups become 
"official" people could start export them for all the properties. I 
could also do this myself but the problem is that being it just my own 
code every time I update if any minimal changes has been made to rna_*.c 
files my code breaks and I have to solve all the conflicts which not 
only is boring and time consuming but can also cause errors by 
distraction if I mistakenly move one line above another and I cannot 
avoid svn updates considering how much the code is changing at this 
time. Also, if others can export groups not only it will be done faster 
of course but also better if users with more 3D and application overall 
usage experience than me would do it. Having more groups exported and 
not having to solve conflicts every time I update would make my 
implementation of AutoLayout faster in addition to providing more 
meaningful test cases.
Exporting groups is very easy and if in doubt of what group type a 
certain group could be, the group type can just be set to GROUP_NONE so 
that a more experienced person can then grep for it in rna_*.c files and 
choose the right type. So the question really comes down to determining 
whether groups are really of some use and are worth the effort. I think 
they are (of course), but I'm accepting negative opinions as well 
(possibly motivated). I'll paste below an example of group definition 
API so that you can have a more clear idea (I indented the part that is 
group specific).

        group= RNA_def_grouprna(brna, "Object");
        RNA_def_grouprna_type(group, GROUP_ROOT);
        RNA_def_grouprna_ui_text(group, "Object", "Object Properties");

        group1= RNA_def_grouprna(brna, "ObjectLayers");
        RNA_def_grouprna_parent(group1, group);
        RNA_def_grouprna_type(group1, GROUP_FLAGS);
        RNA_def_grouprna_ui_text(group1, "Layers", "DOC_BROKEN");

    prop= RNA_def_property(srna, "layers", PROP_BOOLEAN, PROP_NONE);
    RNA_def_property_boolean_sdna(prop, NULL, "lay", 1);
        RNA_def_property_grouprna(prop, group1);
    RNA_def_property_array(prop, 20);
    RNA_def_property_ui_text(prop, "Layers", "Layers the object is on.");
    RNA_def_property_boolean_funcs(prop, NULL, "rna_Object_layer_set");

        group1= RNA_def_grouprna(brna, "ObjectTransform");
        RNA_def_grouprna_parent(group1, group);
        RNA_def_grouprna_ui_text(group1, "Transform", "DOC_BROKEN");

        group2= RNA_def_grouprna(brna, "ObjectTransformNormal");
        RNA_def_grouprna_parent(group2, group1);
        RNA_def_grouprna_type(group2, GROUP_TRIPLET);
        RNA_def_grouprna_ui_text(group2, "Normal", "DOC_BROKEN");

    prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_VECTOR);
    RNA_def_property_float_sdna(prop, NULL, "loc");
        RNA_def_property_grouprna(prop, group2);
    RNA_def_property_ui_text(prop, "Location", "Location of the object.");
    RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, 
"rna_Object_update");

    prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ROTATION);
    RNA_def_property_float_sdna(prop, NULL, "rot");
        RNA_def_property_grouprna(prop, group2);
    RNA_def_property_ui_text(prop, "Rotation", "Rotation of the object.");
    RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, 
"rna_Object_update");

    prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_VECTOR);
    RNA_def_property_float_sdna(prop, NULL, "size");
        RNA_def_property_grouprna(prop, group2);
    RNA_def_property_ui_text(prop, "Scale", "Scaling of the object.");
    RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, 
"rna_Object_update");

If you're wondering why I used grouprna in the names instead of simply 
group this is because RNA_def_group is already being used currently by 
object groups/instancing. So renamed one, I had to rename them all. Of 
course this can be changed later by renaming the function for object groups.

Finally this is a small preview on the just started implementation of 
collections plus some tweaking of other layout elements (I suggest you 
also watch the video I linked in a previous e-mail to have a better 
overall view): http://img145.imageshack.us/img145/1055/83042703wn7.jpg




More information about the Bf-taskforce25 mailing list