Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Yurkovich <jesse.y@gmail.com>2022-06-01 06:57:33 +0300
committerJesse Yurkovich <jesse.y@gmail.com>2022-06-01 06:57:33 +0300
commit12642bdeabeb35802ee196868c9dbd23c153f622 (patch)
tree29f799acff15c51a597846c651ab1c9afd4416ed
parent6cee4049143abf692af6ffb78c109fb0760fe67d (diff)
Fix T96984: Create new image.browse operator for uiTemplateImage layouts
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. Differential Revision: https://developer.blender.org/D14824
-rw-r--r--source/blender/editors/space_image/image_buttons.c5
-rw-r--r--source/blender/editors/space_image/image_intern.h1
-rw-r--r--source/blender/editors/space_image/image_ops.c114
-rw-r--r--source/blender/editors/space_image/space_image.c1
4 files changed, 120 insertions, 1 deletions
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 208928afc1f..d0c21f85472 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -845,7 +845,10 @@ void uiTemplateImage(uiLayout *layout,
row = uiLayoutRow(row, true);
uiLayoutSetEnabled(row, is_packed == false);
- uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE);
+
+ prop = RNA_struct_find_property(&imaptr, "filepath");
+ uiDefAutoButR(block, &imaptr, prop, -1, "", ICON_NONE, 0, 0, 200, UI_UNIT_Y);
+ uiItemO(row, "", ICON_FILEBROWSER, "image.file_browse");
uiItemO(row, "", ICON_FILE_REFRESH, "image.reload");
}
diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h
index 2322420069e..364bec1377d 100644
--- a/source/blender/editors/space_image/image_intern.h
+++ b/source/blender/editors/space_image/image_intern.h
@@ -49,6 +49,7 @@ void IMAGE_OT_new(struct wmOperatorType *ot);
* Called by other space types too.
*/
void IMAGE_OT_open(struct wmOperatorType *ot);
+void IMAGE_OT_file_browse(struct wmOperatorType *ot);
/**
* Called by other space types too.
*/
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 68d342e2143..b01eec53e73 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1535,6 +1535,120 @@ void IMAGE_OT_open(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Browse Image Operator
+ * \{ */
+
+static int image_file_browse_exec(bContext *C, wmOperator *op)
+{
+ Image *ima = op->customdata;
+ if (ima == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ char filepath[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filepath);
+
+ /* If loading into a tiled texture, ensure that the filename is tokenized. */
+ if (ima->source == IMA_SRC_TILED) {
+ char *filename = (char *)BLI_path_basename(filepath);
+ BKE_image_ensure_tile_token(filename);
+ }
+
+ PointerRNA imaptr;
+ PropertyRNA *imaprop;
+ RNA_id_pointer_create(&ima->id, &imaptr);
+ imaprop = RNA_struct_find_property(&imaptr, "filepath");
+
+ RNA_property_string_set(&imaptr, imaprop, filepath);
+ RNA_property_update(C, &imaptr, imaprop);
+
+ return OPERATOR_FINISHED;
+}
+
+static int image_file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Image *ima = image_from_context(C);
+ if (!ima) {
+ return OPERATOR_CANCELLED;
+ }
+
+ char filepath[FILE_MAX];
+ BLI_strncpy(filepath, ima->filepath, sizeof(filepath));
+
+ /* Shift+Click to open the file, Alt+Click to browse a folder in the OS's browser. */
+ if (event->modifier & (KM_SHIFT | KM_ALT)) {
+ wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
+ PointerRNA props_ptr;
+
+ if (event->modifier & KM_ALT) {
+ char *lslash = (char *)BLI_path_slash_rfind(filepath);
+ if (lslash) {
+ *lslash = '\0';
+ }
+ }
+ else if (ima->source == IMA_SRC_TILED) {
+ ImageUser iuser;
+ BKE_imageuser_default(&iuser);
+
+ /* Use the file associated with the active tile. Otherwise use the first tile. */
+ const ImageTile *active = (ImageTile *)BLI_findlink(&ima->tiles, ima->active_tile_index);
+ iuser.tile = active ? active->tile_number : ((ImageTile *)ima->tiles.first)->tile_number;
+ BKE_image_user_file_path(&iuser, ima, filepath);
+ }
+
+ WM_operator_properties_create_ptr(&props_ptr, ot);
+ RNA_string_set(&props_ptr, "filepath", filepath);
+ WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr, NULL);
+ WM_operator_properties_free(&props_ptr);
+
+ return OPERATOR_CANCELLED;
+ }
+
+ /* 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. */
+ op->customdata = ima;
+
+ image_filesel(C, op, filepath);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static bool image_file_browse_poll(bContext *C)
+{
+ return image_from_context(C) != NULL;
+}
+
+void IMAGE_OT_file_browse(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Browse Image";
+ ot->description =
+ "Open an image file browser, hold Shift to open the file, Alt to browse containing "
+ "directory";
+ ot->idname = "IMAGE_OT_file_browse";
+
+ /* api callbacks */
+ ot->exec = image_file_browse_exec;
+ ot->invoke = image_file_browse_invoke;
+ ot->poll = image_file_browse_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_filesel(ot,
+ FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE,
+ FILE_SPECIAL,
+ FILE_OPENFILE,
+ WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
+ FILE_DEFAULTDISPLAY,
+ FILE_SORT_DEFAULT);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Match Movie Length Operator
* \{ */
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 568bd064e3e..2f3c7c74ae7 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -199,6 +199,7 @@ static void image_operatortypes(void)
WM_operatortype_append(IMAGE_OT_new);
WM_operatortype_append(IMAGE_OT_open);
+ WM_operatortype_append(IMAGE_OT_file_browse);
WM_operatortype_append(IMAGE_OT_match_movie_length);
WM_operatortype_append(IMAGE_OT_replace);
WM_operatortype_append(IMAGE_OT_reload);