More information here:
http://lists.blender.org/pipermail/bf-committers/2013-November/042113.html
Details
Diff Detail
- Branch
- work_1
Event Timeline
Added here so I don't forget, will try to review it soon. You can do Commandeer Revision by the way to take over authorship.
I think the implementation would be cleaner if instead of having some way to turn LABEL into TEXT buttons after the fact, you would create a new kind of button that is almost like TEXT. So you might write:
layout.prop(vgroup, "name", show_as_label=True)
I guess it would be a new button type (LABELTEX?). The nice thing about this is that we could potentially reuse it in other places in the UI later as well. For example the little context thing at the top of the properties editor, the name of the object in the lower left of the 3D view or labels in the cycles node tree view in the material properties could be editable that way while still appearing as a label.
Hmmm… Well I tried to avoid adding a new control, but if you think it’s better to do so, I’ll try it. :)
Brecht, in fact I found again why I did not try with a new button type (or even a TEX one, when they are not embossed they do not react to simple click, but only to ctrl-click…). The issue is that in this case, we cannot select the list item itself by clicking on the name.
TEX (or even a new LABELTEX) cannot be considered as a "passive" button, so ui_but_find_mouse_over() will always return this one instead of the listitem below. Even if ui_do_but_TEX() returns WM_UI_HANDLER_CONTINUE, the LISTROW below will never get "activated", as currently Blender does not take into account the situation where you have more than one non-passive buttons stacked.
Solutions I see so far are:
- Use the hackish stuff I use in current patch;
- Declare non-embossed TEX as passive in ui_is_but_interactive(), when CTRL is not pressed (not sure this hack is better than the first one, actually… But looks reasonably simple and doable).
- Explicitly handle several active buttons one above the other (so ui_but_find_mouse_over() would return a list of one or more buttons, in order, and they would all be tested until one returns something else than WM_UI_HANDLER_CONTINUE). I’m not sure we really want to handle such situation on a general basis, though - and this may turn pretty complex with advanced topics like drag'n drop…
On a side note, do you think it would be OK to add another flag member to uiBut (or extend current one to uint64_t)? We are short on space for flags here, now… :/ We could even clearly separate pure-UI flags from more "button-behavior/button-state" ones.
I think option 2. is ok. I have some ideas for better event handling in buttons but that's a bit further along the road, so a simple hack here I'm fine with.
Adding another flag member if fine with me. For example UI_BUT_ALIGN could be split off into a separate but->alignflag and block->alignflag. I prefer such logical grouping over a flag2 as we have in some places.
New feature: Ctrl-click rename of list items in uiList.
In addition to ctrl-click rename, copy/paste (ctrl-C, ctrl-V) also works.
PY API: the only thing required to get this working is at the template level: add a 'rename_propname' parameter to your template call, and it will replace the first (textual) label of each
Dev notes: We are currently using a small hack to get this working: non-embossed text fields used to only activate when ctrl-click, but even though, they would prevent mere click to get to
This is not 100% ideal (main issue is that, if you press ctrl without moving the mouse, non-embossed text field below the mouse won't get activated), but it works pretty well afaik, and doe
A full solution to the issue would probably to get a list of (active) buttons under the mouse, instead of only the top one, and check all of them until we get one actually handling the even
I'm assuming this last code update was accidental or at least not intended to address my comments, so will mark this as "requested changes" again.
Eeeh… no, was not an incident…
But re-reading your previous comment, I think I forgot to answer to a part of it: not turning a label into a text field.
Why I choose to do so is that it allows to reduce the impact on existing code to a minimum: you do not have to edit the existing uiList classes and, even more interesting, the default (C) draw_item function will work as well. The only thing you have to do is give the template the name of the property to rename.
Else, we can force to use a 'layout.prop(…, emboss=False)' instead of current 'layout.label(…)' in custom draw_item functions, and get rid of the 'label to text' hack, but this is not optimal imho (and we’d also have to add the icon_value parameter to prop()).
Note that in any case, we do not need a new button type, as non-embossed text button already behaves as we want. And that using hack 2) (text field is inactive when non-embossed and no ctrl pressed) allowed to greatly simplifies the event handling code on uiList level (in fact, we do not have anything special to do there anymore).
I agree it's an easier change to have rename_propname, but scripts have to make a change regardless, and I think it's much better design to have an actual text property button. If we do it with a new button type this code will be reusable in other places, now it's a list specific hack.
Hmmm… I’m not sure I follow you here… This code is already re-usable in other places - it affects all TEX buttons with UI_EMBOSSN dt flag set (as in, that kind of text field will behaves as a label as long as ctrl is not pressed).
Or do you mean that we should remove completely that specific behavior of non-embossed text fields (which currently need ctrl-clic to enable themselves), and create a new LABELTEX button with this behavior?
In this patch, the only list-specific hack is to turn what is defined as a mere label, without any RNA prop reference, into a text field, using some RNA info given to the template. I do not see how we could reuse that anywhere else in any case? And again, it isn't even mandatory, it’s just an API helper (and because I found more logical to define the prop we want to rename in template call, rather than in uiList classes).
Ah ok, the emboss flag is fine then.
What I don't like is ui_layout_list_set_first_label_as_textfield. If something is a text field, the script should specify that with layout.prop rather than some rename_prop argument to the list template.
Remove the 'label to text field' list template hack.
This gives a more consistent code on the (core) dev POV, but as draw back forces PY dev to use a call to prop() in its draw_item funcs, and (worst thing, imho) makes default uiList class unable to clic-edit their items' names (as it now has no way to know which property to edit).
The default uiList class should be able to figure this out I think, it is drawing the name in a label after all? I think uilist_draw_item_default can get the name property and use uiItemR instead of uiItemL?
- Add auto-clic-rename to default draw_item uiList.
Good point! I don't know why I didn't saw that myself, tbh… :/
And if the "name" prop is a file or dir subtype, you even get the "open browser" button, cool! :)
Looks good to me, pending one comment.
Thanks for your patience, and sorry for being such a pain in the ass, but I think what we ended up here is pretty neat.
| source/blender/editors/interface/interface_widgets.c | ||
|---|---|---|
| 1659 | Can this line be changed to: if ((state & UI_BUT_LIST_ITEM) && !(state & UI_TEXTINPUT)) {Otherwise it shows unreadable black text here. | |
To be clear, if you are happy with this line change and apply it, then go ahead and commit without pushing a new diff here.
If there's a chance, could you add a right-click menu entry "Rename"?
Ctrl+Click / Doubleclick appears to be confusing to some user(s):
http://blenderartists.org/forum/showthread.php?324076-Cannot-rename-vertex-group-in-latest-nightly