diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-11-22 03:56:32 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-11-22 03:56:32 +0400 |
commit | da25b50ccb6a2a2c7d91ec588fe5c1b0e150ae4e (patch) | |
tree | 8abc36b362e479a6ba6aca8a8de417fd1c9d4d47 /source/blender/editors | |
parent | 30fd1ab523393216a66a7debb7e42ec39e40a242 (diff) |
image save operator now shares settings and UI with render & image out node.
details:
- setting format options from python isnt possible anymore since this isnt exposed via op->properties, python should use image.save() function instead.
- image save UI now hides 'Relative' option when copy is selected since it has no effect.
- default image depth is set to 8 or more if the image has no float buffer, otherwise its set to 32 or less.
other fixes:
- image new was adding an image with a filepath set to "untitled", if this file happened to exist in the current directory a save on the generated image would overwrite it, now initialize to empty path.
- BKE_ftype_to_imtype was returning an invalid value if ftype==0.
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 4 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_layout.c | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_utils.c | 4 | ||||
-rw-r--r-- | source/blender/editors/render/render_shading.c | 4 | ||||
-rw-r--r-- | source/blender/editors/sound/sound_ops.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_panels.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_ops.c | 202 |
7 files changed, 113 insertions, 107 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 4b8817334f0..458fe175fbb 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -515,7 +515,7 @@ uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, const char *str, int x1, i uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, int x1, int y1, short x2, short y2, float a1, float a2, const char *tip); uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2); -int uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, int (*check_prop)(struct PropertyRNA *), const char label_align); +int uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, int (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const char label_align); /* Links * @@ -688,7 +688,7 @@ uiBlock *uiLayoutGetBlock(uiLayout *layout); void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv); void uiLayoutSetContextPointer(uiLayout *layout, const char *name, struct PointerRNA *ptr); const char *uiLayoutIntrospect(uiLayout *layout); // XXX - testing -void uiLayoutOperatorButs(const struct bContext *C, struct uiLayout *layout, struct wmOperator *op, int (*check_prop)(struct PropertyRNA *), const char label_align, const short flag); +void uiLayoutOperatorButs(const struct bContext *C, struct uiLayout *layout, struct wmOperator *op, int (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const char label_align, const short flag); struct MenuType *uiButGetMenuType(uiBut *but); void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index c553c1e35ad..84f0c61cd0c 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -2743,7 +2743,7 @@ const char *uiLayoutIntrospect(uiLayout *layout) } /* this function does not initialize the layout, functions can be called on the layout before and after */ -void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,int (*check_prop)(struct PropertyRNA *), const char label_align, const short flag) +void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,int (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const char label_align, const short flag) { if(!op->properties) { IDPropertyTemplate val = {0}; diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 23d5e77b78d..8335668a624 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -130,7 +130,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind return but; } -int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, int (*check_prop)(PropertyRNA *), const char label_align) +int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, int (*check_prop)(PointerRNA *, PropertyRNA *), const char label_align) { uiLayout *split, *col; int flag; @@ -141,7 +141,7 @@ int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, int (*check_prop)(Proper RNA_STRUCT_BEGIN(ptr, prop) { flag= RNA_property_flag(prop); - if(flag & PROP_HIDDEN || (check_prop && check_prop(prop)==FALSE)) + if(flag & PROP_HIDDEN || (check_prop && check_prop(ptr, prop)==FALSE)) continue; if(label_align != '\0') { diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index cf14432754f..f4731eda5bb 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -658,7 +658,7 @@ void TEXTURE_OT_slot_move(wmOperatorType *ot) /********************** environment map operators *********************/ -static int save_envmap(wmOperator *op, Scene *scene, EnvMap *env, char *path, int imtype) +static int save_envmap(wmOperator *op, Scene *scene, EnvMap *env, char *path, const char imtype) { float layout[12]; if ( RNA_struct_find_property(op->ptr, "layout") ) @@ -680,7 +680,7 @@ static int envmap_save_exec(bContext *C, wmOperator *op) Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; Scene *scene = CTX_data_scene(C); //int imtype = RNA_enum_get(op->ptr, "file_type"); - int imtype = scene->r.im_format.imtype; + char imtype = scene->r.im_format.imtype; char path[FILE_MAX]; RNA_string_get(op->ptr, "filepath", path); diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 623cfc48827..dd7ea81d520 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -265,7 +265,7 @@ static int sound_mixdown_invoke(bContext *C, wmOperator *op, wmEvent *event) return WM_operator_filesel(C, op, event); } -static int sound_mixdown_draw_check_prop(PropertyRNA *prop) +static int sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) { const char *prop_id= RNA_property_identifier(prop); return !( strcmp(prop_id, "filepath") == 0 || diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index 7bcaf722827..26083cbe625 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -177,7 +177,7 @@ static void file_panel_operator_header(const bContext *C, Panel *pa) BLI_strncpy(pa->drawname, op->type->name, sizeof(pa->drawname)); } -static int file_panel_check_prop(PropertyRNA *prop) +static int file_panel_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) { const char *prop_id= RNA_property_identifier(prop); return !( strcmp(prop_id, "filepath") == 0 || diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 7e2a86f9324..811233cefa5 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -707,40 +707,6 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot) } /**************** load/replace/save callbacks ******************/ - -/* XXX make dynamic */ -static const EnumPropertyItem image_file_type_items[] = { - {R_TARGA, "TARGA", 0, "Targa", ""}, - {R_RAWTGA, "TARGA RAW", 0, "Targa Raw", ""}, - {R_PNG, "PNG", 0, "PNG", ""}, -#ifdef WITH_DDS - {R_DDS, "DDS", 0, "DirectDraw Surface", ""}, -#endif - {R_BMP, "BMP", 0, "BMP", ""}, - {R_JPEG90, "JPEG", 0, "Jpeg", ""}, -#ifdef WITH_OPENJPEG - {R_JP2, "JPEG_2000", 0, "Jpeg 2000", ""}, -#endif - {R_IRIS, "IRIS", 0, "Iris", ""}, -#ifdef WITH_TIFF - {R_TIFF, "TIFF", 0, "Tiff", ""}, -#endif -#ifdef WITH_DDS - {R_RADHDR, "RADIANCE_HDR", 0, "Radiance HDR", ""}, -#endif -#ifdef WITH_CINEON - {R_CINEON, "CINEON", 0, "Cineon", ""}, - {R_DPX, "DPX", 0, "DPX", ""}, -#endif -#ifdef WITH_OPENEXR - {R_OPENEXR, "OPENEXR", 0, "OpenEXR", ""}, - /* saving sequences of multilayer won't work, they copy buffers */ - /*if(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER); - else*/ - {R_MULTILAYER, "MULTILAYER", 0, "MultiLayer", ""}, -#endif - {0, NULL, 0, NULL, NULL}}; - static void image_filesel(bContext *C, wmOperator *op, const char *path) { RNA_string_set(op->ptr, "filepath", path); @@ -943,19 +909,42 @@ void IMAGE_OT_replace(wmOperatorType *ot) typedef struct { /* matching scene->r settings */ - short planes, imtype, subimtype, quality; + //short planes, imtype, subimtype, quality; + ImageFormatData im_format; char filepath[FILE_MAX]; /* keep absolute */ } SaveImageOptions; static void save_image_options_defaults(SaveImageOptions *simopts) { - simopts->planes= R_IMF_PLANES_RGB; - simopts->imtype= R_PNG; - simopts->subimtype= 0; - simopts->quality= 90; + memset(&simopts->im_format, 0, sizeof(simopts->im_format)); + simopts->im_format.planes= R_IMF_PLANES_RGB; + simopts->im_format.imtype= R_PNG; + simopts->im_format.quality= 90; + simopts->im_format.compress= 90; simopts->filepath[0]= '\0'; } +static char imtype_best_depth(ImBuf *ibuf, const char imtype) +{ + const char depth_ok= BKE_imtype_is_depth_ok(imtype); + + if (ibuf->rect_float) { + if (depth_ok & R_IMF_CHAN_DEPTH_32) return R_IMF_CHAN_DEPTH_32; + if (depth_ok & R_IMF_CHAN_DEPTH_24) return R_IMF_CHAN_DEPTH_24; + if (depth_ok & R_IMF_CHAN_DEPTH_16) return R_IMF_CHAN_DEPTH_16; + if (depth_ok & R_IMF_CHAN_DEPTH_12) return R_IMF_CHAN_DEPTH_12; + return R_IMF_CHAN_DEPTH_8; + } + else { + if (depth_ok & R_IMF_CHAN_DEPTH_8) return R_IMF_CHAN_DEPTH_8; + if (depth_ok & R_IMF_CHAN_DEPTH_12) return R_IMF_CHAN_DEPTH_12; + if (depth_ok & R_IMF_CHAN_DEPTH_16) return R_IMF_CHAN_DEPTH_16; + if (depth_ok & R_IMF_CHAN_DEPTH_24) return R_IMF_CHAN_DEPTH_24; + if (depth_ok & R_IMF_CHAN_DEPTH_32) return R_IMF_CHAN_DEPTH_32; + return R_IMF_CHAN_DEPTH_8; /* fallback, should not get here */ + } +} + static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima, Scene *scene, const short guess_path) { void *lock; @@ -963,34 +952,41 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima, if(ibuf) { Image *ima= sima->image; + short is_depth_set= FALSE; - simopts->planes= ibuf->planes; + simopts->im_format.planes= ibuf->planes; if(ELEM(ima->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) { - simopts->imtype= scene->r.im_format.imtype; - simopts->planes= scene->r.im_format.planes; + /* imtype */ + simopts->im_format= scene->r.im_format; + is_depth_set= TRUE; } else if (ima->source == IMA_SRC_GENERATED) { - simopts->imtype= R_PNG; + simopts->im_format.imtype= R_PNG; } else { - simopts->imtype= BKE_ftype_to_imtype(ibuf->ftype); + simopts->im_format.imtype= BKE_ftype_to_imtype(ibuf->ftype); } //simopts->subimtype= scene->r.subimtype; /* XXX - this is lame, we need to make these available too! */ - simopts->quality= ibuf->ftype & 0xff; + simopts->im_format.quality= ibuf->ftype & 0xff; BLI_strncpy(simopts->filepath, ibuf->name, sizeof(simopts->filepath)); /* sanitize all settings */ /* unlikely but just incase */ - if (ELEM3(simopts->planes, R_IMF_PLANES_BW, R_IMF_PLANES_RGB, R_IMF_PLANES_RGBA) == 0) { - simopts->planes= R_IMF_PLANES_RGBA; + if (ELEM3(simopts->im_format.planes, R_IMF_PLANES_BW, R_IMF_PLANES_RGB, R_IMF_PLANES_RGBA) == 0) { + simopts->im_format.planes= R_IMF_PLANES_RGBA; + } + + /* depth, account for float buffer and format support */ + if (is_depth_set == FALSE) { + simopts->im_format.depth= imtype_best_depth(ibuf, simopts->im_format.imtype); } /* some formats dont use quality so fallback to scenes quality */ - if (simopts->quality == 0) { - simopts->quality= scene->r.im_format.quality; + if (simopts->im_format.quality == 0) { + simopts->im_format.quality= scene->r.im_format.quality; } /* check for empty path */ @@ -1009,19 +1005,11 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima, return (ibuf != NULL); } -static void save_image_options_from_op(SaveImageOptions *simopts, wmOperator *op, Scene *evil_scene) +static void save_image_options_from_op(SaveImageOptions *simopts, wmOperator *op) { - if (RNA_property_is_set(op->ptr, "color_mode")) simopts->planes= RNA_enum_get(op->ptr, "color_mode"); - if (RNA_property_is_set(op->ptr, "file_format")) simopts->imtype= RNA_enum_get(op->ptr, "file_format"); - -#if 0 - if (RNA_property_is_set(op->ptr, "subimtype")) simopts->subimtype= RNA_enum_get(op->ptr, "subimtype"); // XXX -#else -// simopts->subimtype= evil_scene->r.subimtype; - (void)evil_scene; -#endif - - if (RNA_property_is_set(op->ptr, "file_quality")) simopts->quality= RNA_int_get(op->ptr, "file_quality"); + if (op->customdata) { + simopts->im_format= *(ImageFormatData *)op->customdata; + } if (RNA_property_is_set(op->ptr, "filepath")) { RNA_string_get(op->ptr, "filepath", simopts->filepath); @@ -1031,10 +1019,9 @@ static void save_image_options_from_op(SaveImageOptions *simopts, wmOperator *op static void save_image_options_to_op(SaveImageOptions *simopts, wmOperator *op) { - RNA_enum_set(op->ptr, "color_mode", simopts->planes); - RNA_enum_set(op->ptr, "file_format", simopts->imtype); - // RNA_enum_set(op->ptr, "subimtype", simopts->subimtype); - RNA_int_set(op->ptr, "file_quality", simopts->quality); + if (op->customdata) { + *(ImageFormatData *)op->customdata= simopts->im_format; + } RNA_string_set(op->ptr, "filepath", simopts->filepath); } @@ -1060,10 +1047,10 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI if(ima->type == IMA_TYPE_R_RESULT) { /* enforce user setting for RGB or RGBA, but skip BW */ - if(simopts->planes==R_IMF_PLANES_RGBA) { + if(simopts->im_format.planes==R_IMF_PLANES_RGBA) { ibuf->planes= R_IMF_PLANES_RGBA; } - else if(simopts->planes==R_IMF_PLANES_RGB) { + else if(simopts->im_format.planes==R_IMF_PLANES_RGB) { ibuf->planes= R_IMF_PLANES_RGB; } } @@ -1075,11 +1062,11 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI } } - if(simopts->imtype==R_MULTILAYER) { + if(simopts->im_format.imtype==R_MULTILAYER) { Scene *scene= CTX_data_scene(C); RenderResult *rr= BKE_image_acquire_renderresult(scene, ima); if(rr) { - RE_WriteRenderResult(op->reports, rr, simopts->filepath, simopts->quality); + RE_WriteRenderResult(op->reports, rr, simopts->filepath, simopts->im_format.quality); ok= TRUE; } else { @@ -1088,15 +1075,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI BKE_image_release_renderresult(scene, ima); } else { - ImageFormatData imf= {0}; - - /* todo, make operator use template, this works for now */ - imf.imtype= simopts->imtype; - imf.quality= simopts->quality; - imf.compress= simopts->quality; - imf.depth= R_IMF_CHAN_DEPTH_8; - - if (BKE_write_ibuf(ibuf, simopts->filepath, &imf)) { + if (BKE_write_ibuf(ibuf, simopts->filepath, &simopts->im_format)) { ok= TRUE; } } @@ -1150,27 +1129,40 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI ED_space_image_release_buffer(sima, lock); } +static void image_save_as_free(wmOperator *op) +{ + if (op->customdata) { + MEM_freeN(op->customdata); + op->customdata= NULL; + } +} + static int image_save_as_exec(bContext *C, wmOperator *op) { SpaceImage *sima= CTX_wm_space_image(C); SaveImageOptions simopts; + save_image_options_defaults(&simopts); + /* just incase to initialize values, * these should be set on invoke or by the caller. */ - save_image_options_defaults(&simopts); - save_image_options_from_op(&simopts, op, CTX_data_scene(C)); + save_image_options_init(&simopts, sima, CTX_data_scene(C), 0); + + save_image_options_from_op(&simopts, op); save_image_doit(C, sima, op, &simopts, TRUE); + image_save_as_free(op); return OPERATOR_FINISHED; } static int image_save_as_check(bContext *UNUSED(C), wmOperator *op) { + ImageFormatData *imf= op->customdata; char filepath[FILE_MAX]; RNA_string_get(op->ptr, "filepath", filepath); - if(BKE_add_image_extension(filepath, RNA_enum_get(op->ptr, "file_format"))) { + if(BKE_add_image_extension(filepath, imf->imtype)) { RNA_string_set(op->ptr, "filepath", filepath); return TRUE; } @@ -1196,15 +1188,36 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(eve RNA_boolean_set(op->ptr, "copy", TRUE); } - // XXX note: we can give default menu enums to operator for this + op->customdata= MEM_mallocN(sizeof(simopts.im_format), __func__); + memcpy(op->customdata, &simopts.im_format, sizeof(simopts.im_format)); + image_filesel(C, op, simopts.filepath); return OPERATOR_RUNNING_MODAL; } -#if 0 -static void image_save_as_draw(bContext *C, wmOperator *op) +static int image_save_as_cancel(bContext *UNUSED(C), wmOperator *op) +{ + image_save_as_free(op); + + return OPERATOR_CANCELLED; +} + +static int image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +{ + const char *prop_id= RNA_property_identifier(prop); + + return !(strcmp(prop_id, "filepath") == 0 || + strcmp(prop_id, "directory") == 0 || + strcmp(prop_id, "filename") == 0 || + /* when saving a copy, relative path has no effect */ + ((strcmp(prop_id, "relative_path") == 0) && RNA_boolean_get(ptr, "copy")) + ); +} + +static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op) { + uiLayout *layout= op->layout; ImageFormatData *imf= op->customdata; PointerRNA ptr; @@ -1213,14 +1226,13 @@ static void image_save_as_draw(bContext *C, wmOperator *op) uiTemplateImageSettings(layout, &ptr); /* main draw call */ - RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - uiDefAutoButsRNA(layout, &ptr, NULL, '\0'); + RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); + uiDefAutoButsRNA(layout, &ptr, image_save_as_draw_check_prop, '\0'); } -#endif void IMAGE_OT_save_as(wmOperatorType *ot) { - PropertyRNA *prop; +// PropertyRNA *prop; /* identifiers */ ot->name= "Save As Image"; @@ -1230,23 +1242,17 @@ void IMAGE_OT_save_as(wmOperatorType *ot) ot->exec= image_save_as_exec; ot->check= image_save_as_check; ot->invoke= image_save_as_invoke; - // ot->ui= image_save_as_draw; + ot->cancel= image_save_as_cancel; + ot->ui= image_save_as_draw; ot->poll= space_image_buffer_exists_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - - /* format options */ - RNA_def_enum(ot->srna, "file_format", image_file_type_items, R_PNG, "File Type", "File type to save image as"); - RNA_def_enum(ot->srna, "color_mode", image_color_mode_items, R_IMF_PLANES_RGB, "Channels", "Image channels to save"); - prop= RNA_def_int(ot->srna, "file_quality", 90, 0, 100, "Quality", "", 0, 100); - RNA_def_property_subtype(prop, PROP_PERCENTAGE); + RNA_def_boolean(ot->srna, "copy", 0, "Copy", "Create a new image file without modifying the current image in blender"); WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); - - RNA_def_boolean(ot->srna, "copy", 0, "Copy", "Create a new image file without modifying the current image in blender"); } /******************** save image operator ********************/ @@ -1259,7 +1265,7 @@ static int image_save_exec(bContext *C, wmOperator *op) if (save_image_options_init(&simopts, sima, scene, FALSE) == 0) return OPERATOR_CANCELLED; - save_image_options_from_op(&simopts, op, scene); + save_image_options_from_op(&simopts, op); if (BLI_exists(simopts.filepath) && BLI_file_is_writable(simopts.filepath)) { save_image_doit(C, sima, op, &simopts, FALSE); |