Page MenuHome

Fix T96984: Create new image.browse operator for uiTemplateImage layouts
ClosedPublic

Authored by Jesse Yurkovich (deadpin) on May 3 2022, 7:00 AM.

Details

Summary

The existing BUTTONS_OT_file_browse operator that's used for
uiTemplateImage layouts fails to work correctly with UDIM textures.

This is mainly due to it not realizing that it must tokenize the
filepath before signaling that an update has been made. It also doesn't
work correctly when executing its SHIFT-click behavior to open the image
in an external application. Lastly, it doesn't set the filters to Images
and Movies which is suboptimal for the user.

The new operator takes the unique features of BUTTONS_OT_file_browse
and creates a customized variant better suited for images.


How did this work before the bug report? In many cases it really didn't.

When attempting to load a file from a different UDIM set into the
current one, if there was a mismatch in tile configuration, things would
load incorrectly.

When attempting to load a file from the same UDIM set, the filename for
the image would change (confusingly) but still work accidentally.

In all cases the the SHIFT-click behavior would be unexpected. It would
either only open the first tile's image, and not the active tile as
would be expected Or, in 3.1, an error would be produced.

Diff Detail

Repository
rB Blender

Event Timeline

Jesse Yurkovich (deadpin) requested review of this revision.May 3 2022, 7:00 AM
Jesse Yurkovich (deadpin) created this revision.

Ping for the reviewers, since this is a fix for a high priority bug.

Julian Eisel (Severin) requested changes to this revision.May 23 2022, 4:58 PM

Looks fine mostly, just two small things.

Lastly, it doesn't set the filters to Images and Movies which is suboptimal for the user.

It still doesn't do that for me. You'd have to use FILE_IMGDISPLAY instead of FILE_DEFAULTDISPLAY for this.

source/blender/editors/space_image/image_ops.c
1621–1623

This shouldn't be needed. image_browse_exec() can just call image_from_context() again. The struct and the customdata management can be removed then.

This revision now requires changes to proceed.May 23 2022, 4:58 PM

FILE_IMGDISPLAY seems to switch to thumbnail mode which wasn't strictly the intent here. The main image.open operator isn't even bold enough to try such a thing :) The filters are set to Image and Movies for me though. Are you sure it's not in your case?

source/blender/editors/space_image/image_ops.c
1621–1623

You would think that's the case, but it appears not so :-/ The context during invoke has the image correctly attached to it, but not during execute, so null is returned. There is a fallback check but that's only for space image data (sima) which doesn't work when this template is used in other editors (like for Image empties or Camera backgrounds).

FILE_IMGDISPLAY seems to switch to thumbnail mode which wasn't strictly the intent here.

A sorry, thought that was your intention, but you actually meant the filters :) I'd still say using thumbnail display makes sense for this and IMAGE_OT_open.

source/blender/editors/space_image/image_buttons.c
849

PropertyRNA *prop is already declared above, so this shadows. Just do:

prop = RNA_struct_find_property(&imaptr, "filepath");
850

All sub-layouts share the same block, so no need to query it again. Just pass the existing block.

source/blender/editors/space_image/image_ops.c
1621–1623

Apparently the image is passed via the button context (and if that fails through the image editor context, and if that fails, directly queried from the image editor). This button context isn't available anymore when the File Browser calls the exec() callback. It would be nice to support restoring it, like we already restore the window, area & region context, but I'm not at all keen on it since the data passed to the button context might get freed while the File Browser is open. In practice it probably would be fine, at least for IDs, since these are only freed/reallocated over undo/redo, which cancels the file operation anyway. Still not keen about it.

So I'd say querying the data in the invoke() and storing it in the custom data is indeed the best way to go for now.
However, you don't need a separate struct and allocate memory for this. Just assign the image to op->customdata directly. And please add a comment, something like:

/* The image is typically passed to the operator via layout/button context (e.g.
 * #uiLayoutSetContextPointer()). The File Browser doesn't support restoring this context when
 * calling `exec()` though, so we have to pass it the image via custom data. */

Lastly, I'd suggest adding a poll() function that checks if image_from_context() succeeds, so it's grayed out in the UI and search menus if not.

One last thing, I notice this new operator differs quite a bit from IMAGE_OT_open(). I see the "open" one is more complicated, since it actually creates an image data-block, supports loading sequences etc., while this new operator only replaces the referenced image file (at the current frame?)? Either way, the name "Browse" is quite vague, I'd make it more clear. How about IMAGE_OT_replace?

There's already a replace operator for images, which does something different.

I think IMAGE_OT_file_browse could be good, for consistency with BUTTONS_OT_file_browse.

This revision is now accepted and ready to land.May 31 2022, 3:50 PM