UI: use single column layout for image settings panels

This commit is contained in:
2019-05-19 14:51:21 +02:00
parent 7aaa7aa9dd
commit 2ff393bb98
3 changed files with 275 additions and 262 deletions

View File

@@ -27,7 +27,8 @@ class DataButtonsPanel:
@classmethod
def poll(cls, context):
return (context.object and context.object.type == 'EMPTY')
ob = context.object
return (ob and ob.type == 'EMPTY')
class DATA_PT_empty(DataButtonsPanel, Panel):
@@ -36,6 +37,7 @@ class DATA_PT_empty(DataButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
ob = context.object
@@ -43,11 +45,6 @@ class DATA_PT_empty(DataButtonsPanel, Panel):
layout.prop(ob, "empty_display_size", text="Size")
if ob.empty_display_type == 'IMAGE':
layout.template_ID(ob, "data", open="image.open", unlink="object.unlink_data")
layout.template_image(ob, "data", ob.image_user, compact=True)
layout.row(align=True).row(align=True)
layout.prop(ob, "use_empty_image_alpha")
col = layout.column()
@@ -65,8 +62,25 @@ class DATA_PT_empty(DataButtonsPanel, Panel):
col.prop(ob, "show_empty_image_perspective", text="Display Perspective")
class DATA_PT_empty_image(DataButtonsPanel, Panel):
bl_label = "Image"
@classmethod
def poll(cls, context):
ob = context.object
return (ob and ob.type == 'EMPTY' and ob.empty_display_type == 'IMAGE')
def draw(self, context):
layout = self.layout
ob = context.object
layout.template_ID(ob, "data", open="image.open", unlink="object.unlink_data")
layout.separator();
layout.template_image(ob, "data", ob.image_user, compact=True)
classes = (
DATA_PT_empty,
DATA_PT_empty_image,
)
if __name__ == "__main__": # only for live edit.

View File

@@ -490,7 +490,6 @@ class NODE_PT_active_node_properties(Panel):
bl_category = "Item"
bl_label = "Properties"
bl_options = {'DEFAULT_CLOSED'}
bl_parent_id = 'NODE_PT_active_node_generic'
@classmethod
def poll(cls, context):

View File

@@ -63,81 +63,6 @@
#define B_NOP -1
#define MAX_IMAGE_INFO_LEN 128
/* proto */
static void image_info(
Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf, char *str, size_t len)
{
size_t ofs = 0;
str[0] = 0;
if (ima == NULL) {
return;
}
if (ibuf == NULL) {
ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Can't Load Image"), len - ofs);
}
else {
if (ima->source == IMA_SRC_MOVIE) {
ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Movie"), len - ofs);
if (BKE_image_has_anim(ima)) {
ofs += BLI_snprintf(
str + ofs,
len - ofs,
IFACE_(" %d frs"),
IMB_anim_get_duration(((ImageAnim *)ima->anims.first)->anim, IMB_TC_RECORD_RUN));
}
}
else {
ofs += BLI_strncpy_rlen(str, IFACE_("Image"), len - ofs);
}
ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(": size %d x %d,"), ibuf->x, ibuf->y);
if (ibuf->rect_float) {
if (ibuf->channels != 4) {
ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_("%d float channel(s)"), ibuf->channels);
}
else if (ibuf->planes == R_IMF_PLANES_RGBA) {
ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA float"), len - ofs);
}
else {
ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB float"), len - ofs);
}
}
else {
if (ibuf->planes == R_IMF_PLANES_RGBA) {
ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA byte"), len - ofs);
}
else {
ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB byte"), len - ofs);
}
}
if (ibuf->zbuf || ibuf->zbuf_float) {
ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" + Z"), len - ofs);
}
if (ima->source == IMA_SRC_SEQUENCE) {
const char *file = BLI_last_slash(ibuf->name);
if (file == NULL) {
file = ibuf->name;
}
else {
file++;
}
ofs += BLI_snprintf(str + ofs, len - ofs, ", %s", file);
}
}
/* the frame number, even if we cant */
if (ima->source == IMA_SRC_SEQUENCE) {
/* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */
const int framenr = BKE_image_user_frame_get(iuser, CFRA, NULL);
ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(", Frame: %d"), framenr);
}
}
/* gets active viewer user */
struct ImageUser *ntree_get_active_iuser(bNodeTree *ntree)
{
@@ -823,6 +748,22 @@ static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
RNA_property_update(C, &cb->ptr, cb->prop);
}
static bool image_has_alpha(Image *ima, ImageUser *iuser)
{
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf == NULL) {
return false;
}
int imtype = BKE_image_ftype_to_imtype(ibuf->ftype, &ibuf->foptions);
char valid_channels = BKE_imtype_valid_channels(imtype, false);
bool has_alpha = (valid_channels & IMA_CHAN_FLAG_ALPHA) != 0;
BKE_image_release_ibuf(ima, ibuf, NULL);
return has_alpha;
}
void uiTemplateImage(uiLayout *layout,
bContext *C,
PointerRNA *ptr,
@@ -831,24 +772,11 @@ void uiTemplateImage(uiLayout *layout,
bool compact,
bool multiview)
{
PropertyRNA *prop;
PointerRNA imaptr;
RNAUpdateCb *cb;
Image *ima;
ImageUser *iuser;
Scene *scene = CTX_data_scene(C);
SpaceImage *space_image = CTX_wm_space_image(C);
uiLayout *row, *split, *col;
uiBlock *block;
char str[MAX_IMAGE_INFO_LEN];
void *lock;
if (!ptr->data) {
return;
}
prop = RNA_struct_find_property(ptr, propname);
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
if (!prop) {
printf(
"%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
@@ -863,22 +791,19 @@ void uiTemplateImage(uiLayout *layout,
return;
}
block = uiLayoutGetBlock(layout);
uiBlock *block = uiLayoutGetBlock(layout);
imaptr = RNA_property_pointer_get(ptr, prop);
ima = imaptr.data;
iuser = userptr->data;
PointerRNA imaptr = RNA_property_pointer_get(ptr, prop);
Image *ima = imaptr.data;
ImageUser *iuser = userptr->data;
Scene *scene = CTX_data_scene(C);
BKE_image_user_frame_calc(iuser, (int)scene->r.cfra);
cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
cb->ptr = *ptr;
cb->prop = prop;
cb->iuser = iuser;
uiLayoutSetContextPointer(layout, "edit_image", &imaptr);
uiLayoutSetContextPointer(layout, "edit_image_user", userptr);
SpaceImage *space_image = CTX_wm_space_image(C);
if (!compact && (space_image == NULL || iuser != &space_image->iuser)) {
uiTemplateID(layout,
C,
@@ -889,165 +814,178 @@ void uiTemplateImage(uiLayout *layout,
NULL,
UI_TEMPLATE_ID_FILTER_ALL,
false);
if (ima != NULL) {
uiItemS(layout);
}
}
if (ima) {
UI_block_funcN_set(block, rna_update_cb, MEM_dupallocN(cb), NULL);
if (ima == NULL) {
return;
}
if (ima->source == IMA_SRC_VIEWER) {
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
image_info(scene, iuser, ima, ibuf, str, MAX_IMAGE_INFO_LEN);
BKE_image_release_ibuf(ima, ibuf, lock);
if (ima->source == IMA_SRC_VIEWER) {
/* Viewer images. */
uiTemplateImageInfo(layout, C, ima, iuser);
uiItemL(layout, ima->id.name + 2, ICON_NONE);
uiItemL(layout, str, ICON_NONE);
if (ima->type == IMA_TYPE_COMPOSITE) {
}
else if (ima->type == IMA_TYPE_R_RESULT) {
/* browse layer/passes */
RenderResult *rr;
const float dpi_fac = UI_DPI_FAC;
const int menus_width = 230 * dpi_fac;
if (ima->type == IMA_TYPE_COMPOSITE) {
}
else if (ima->type == IMA_TYPE_R_RESULT) {
/* browse layer/passes */
RenderResult *rr;
const float dpi_fac = UI_DPI_FAC;
const int menus_width = 230 * dpi_fac;
/* use BKE_image_acquire_renderresult so we get the correct slot in the menu */
rr = BKE_image_acquire_renderresult(scene, ima);
uiblock_layer_pass_buttons(layout, ima, rr, iuser, menus_width, &ima->render_slot);
BKE_image_release_renderresult(scene, ima);
}
/* use BKE_image_acquire_renderresult so we get the correct slot in the menu */
rr = BKE_image_acquire_renderresult(scene, ima);
uiblock_layer_pass_buttons(layout, ima, rr, iuser, menus_width, &ima->render_slot);
BKE_image_release_renderresult(scene, ima);
}
return;
}
/* Set custom callback for property updates. */
RNAUpdateCb *cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
cb->ptr = *ptr;
cb->prop = prop;
cb->iuser = iuser;
UI_block_funcN_set(block, rna_update_cb, cb, NULL);
/* Disable editing if image was modified, to avoid losing changes. */
const bool is_dirty = BKE_image_is_dirty(ima);
if (is_dirty) {
uiLayout *row = uiLayoutRow(layout, true);
uiItemO(row, IFACE_("Save"), ICON_NONE, "image.save");
uiItemO(row, IFACE_("Discard Changes"), ICON_NONE, "image.reload");
uiItemS(layout);
}
layout = uiLayoutColumn(layout, false);
uiLayoutSetEnabled(layout, !is_dirty);
uiLayoutSetPropDecorate(layout, false);
/* Image source */
{
uiLayout *col = uiLayoutColumn(layout, false);
uiLayoutSetPropSep(col, true);
uiItemR(col, &imaptr, "source", 0, NULL, ICON_NONE);
}
/* Filepath */
const bool is_packed = BKE_image_has_packedfile(ima);
const bool no_filepath = is_packed && !BKE_image_has_filepath(ima);
if ((ima->source != IMA_SRC_GENERATED) && !no_filepath) {
uiItemS(layout);
uiLayout *row = uiLayoutRow(layout, true);
if (is_packed) {
uiItemO(row, "", ICON_PACKAGE, "image.unpack");
}
else {
/* Disable editing if image was modified, to avoid losing changes. */
const bool is_dirty = BKE_image_is_dirty(ima);
if (is_dirty) {
row = uiLayoutRow(layout, true);
uiItemO(row, IFACE_("Save"), ICON_NONE, "image.save");
uiItemO(row, IFACE_("Discard Changes"), ICON_NONE, "image.reload");
uiItemS(layout);
}
layout = uiLayoutColumn(layout, false);
uiLayoutSetEnabled(layout, !is_dirty);
/* Image source */
uiItemR(layout, &imaptr, "source", 0, NULL, ICON_NONE);
/* Filepath */
const bool is_packed = BKE_image_has_packedfile(ima);
const bool no_filepath = is_packed && !BKE_image_has_filepath(ima);
if ((ima->source != IMA_SRC_GENERATED) && !no_filepath) {
row = uiLayoutRow(layout, true);
if (is_packed) {
uiItemO(row, "", ICON_PACKAGE, "image.unpack");
}
else {
uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack");
}
row = uiLayoutRow(row, true);
uiLayoutSetEnabled(row, is_packed == false);
uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE);
uiItemO(row, "", ICON_FILE_REFRESH, "image.reload");
}
/* Image layers and Info */
if (ima->type == IMA_TYPE_MULTILAYER && ima->rr) {
const float dpi_fac = UI_DPI_FAC;
uiblock_layer_pass_buttons(layout, ima, ima->rr, iuser, 230 * dpi_fac, NULL);
}
else if (ima->source != IMA_SRC_GENERATED) {
if (compact == 0) {
uiTemplateImageInfo(layout, C, ima, iuser);
}
}
uiItemS(layout);
col = uiLayoutColumn(layout, false);
uiTemplateColorspaceSettings(col, &imaptr, "colorspace_settings");
uiItemR(col, &imaptr, "use_view_as_render", 0, NULL, ICON_NONE);
uiItemS(layout);
if (ima->source != IMA_SRC_GENERATED) {
if (compact == 0) { /* background image view doesn't need these */
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
bool has_alpha = true;
if (ibuf) {
int imtype = BKE_image_ftype_to_imtype(ibuf->ftype, &ibuf->foptions);
char valid_channels = BKE_imtype_valid_channels(imtype, false);
has_alpha = (valid_channels & IMA_CHAN_FLAG_ALPHA) != 0;
BKE_image_release_ibuf(ima, ibuf, NULL);
}
if (multiview) {
if ((scene->r.scemode & R_MULTIVIEW) != 0) {
uiItemR(layout, &imaptr, "use_multiview", 0, NULL, ICON_NONE);
if (RNA_boolean_get(&imaptr, "use_multiview")) {
uiTemplateImageViews(layout, &imaptr);
}
}
}
if (has_alpha) {
col = uiLayoutColumn(layout, false);
uiItemR(col, &imaptr, "alpha_mode", 0, IFACE_("Alpha"), ICON_NONE);
/* Alpha mode has no effect for non-color data. */
bool is_data = IMB_colormanagement_space_name_is_data(ima->colorspace_settings.name);
uiLayoutSetActive(col, !is_data);
}
if (ima->source == IMA_SRC_MOVIE) {
col = uiLayoutColumn(layout, false);
uiItemR(col, &imaptr, "use_deinterlace", 0, IFACE_("Deinterlace"), ICON_NONE);
}
}
}
if (BKE_image_is_animated(ima)) {
uiItemS(layout);
split = uiLayoutSplit(layout, 0.0f, false);
col = uiLayoutColumn(split, false);
BLI_snprintf(str, sizeof(str), IFACE_("(%d) Frames"), iuser->framenr);
uiItemR(col, userptr, "frame_duration", 0, str, ICON_NONE);
uiItemR(col, userptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
uiItemR(col, userptr, "frame_offset", 0, NULL, ICON_NONE);
col = uiLayoutColumn(split, false);
uiItemO(col, NULL, ICON_NONE, "IMAGE_OT_match_movie_length");
uiItemR(col, userptr, "use_auto_refresh", 0, NULL, ICON_NONE);
uiItemR(col, userptr, "use_cyclic", 0, NULL, ICON_NONE);
}
else if (ima->source == IMA_SRC_GENERATED) {
split = uiLayoutSplit(layout, 0.0f, false);
col = uiLayoutColumn(split, true);
uiItemR(col, &imaptr, "generated_width", 0, "X", ICON_NONE);
uiItemR(col, &imaptr, "generated_height", 0, "Y", ICON_NONE);
uiItemR(col, &imaptr, "use_generated_float", 0, NULL, ICON_NONE);
uiItemR(split, &imaptr, "generated_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
if (ima->gen_type == IMA_GENTYPE_BLANK) {
uiItemR(layout, &imaptr, "generated_color", 0, NULL, ICON_NONE);
}
}
uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack");
}
UI_block_funcN_set(block, NULL, NULL, NULL);
row = uiLayoutRow(row, true);
uiLayoutSetEnabled(row, is_packed == false);
uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE);
uiItemO(row, "", ICON_FILE_REFRESH, "image.reload");
}
MEM_freeN(cb);
/* Image layers and Info */
if (ima->type == IMA_TYPE_MULTILAYER && ima->rr) {
uiItemS(layout);
const float dpi_fac = UI_DPI_FAC;
uiblock_layer_pass_buttons(layout, ima, ima->rr, iuser, 230 * dpi_fac, NULL);
}
else if (ima->source == IMA_SRC_GENERATED) {
uiItemS(layout);
/* Generated */
uiLayout *col = uiLayoutColumn(layout, false);
uiLayoutSetPropSep(col, true);
uiLayout *sub = uiLayoutColumn(col, true);
uiItemR(sub, &imaptr, "generated_width", 0, "X", ICON_NONE);
uiItemR(sub, &imaptr, "generated_height", 0, "Y", ICON_NONE);
uiItemR(col, &imaptr, "use_generated_float", 0, NULL, ICON_NONE);
uiItemS(col);
uiItemR(col, &imaptr, "generated_type", UI_ITEM_R_EXPAND, IFACE_("Type"), ICON_NONE);
if (ima->gen_type == IMA_GENTYPE_BLANK) {
uiItemR(col, &imaptr, "generated_color", 0, NULL, ICON_NONE);
}
}
else if (compact == 0) {
uiTemplateImageInfo(layout, C, ima, iuser);
}
if (BKE_image_is_animated(ima)) {
/* Animation */
uiItemS(layout);
uiLayout *col = uiLayoutColumn(layout, true);
uiLayoutSetPropSep(col, true);
uiLayout *sub = uiLayoutColumn(col, true);
uiLayout *row = uiLayoutRow(sub, true);
uiItemR(row, userptr, "frame_duration", 0, IFACE_("Frames"), ICON_NONE);
uiItemO(row, "", ICON_FILE_REFRESH, "IMAGE_OT_match_movie_length");
uiItemR(sub, userptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
uiItemR(sub, userptr, "frame_offset", 0, NULL, ICON_NONE);
uiItemR(col, userptr, "use_cyclic", 0, NULL, ICON_NONE);
uiItemR(col, userptr, "use_auto_refresh", 0, NULL, ICON_NONE);
if (ima->source == IMA_SRC_MOVIE && compact == 0) {
uiItemR(col, &imaptr, "use_deinterlace", 0, IFACE_("Deinterlace"), ICON_NONE);
}
}
/* Multiview */
if (multiview && compact == 0) {
if ((scene->r.scemode & R_MULTIVIEW) != 0) {
uiItemS(layout);
uiLayout *col = uiLayoutColumn(layout, false);
uiLayoutSetPropSep(col, true);
uiItemR(col, &imaptr, "use_multiview", 0, NULL, ICON_NONE);
if (RNA_boolean_get(&imaptr, "use_multiview")) {
uiTemplateImageViews(layout, &imaptr);
}
}
}
/* Colorspace and alpha */
{
uiItemS(layout);
uiLayout *col = uiLayoutColumn(layout, false);
uiLayoutSetPropSep(col, true);
uiTemplateColorspaceSettings(col, &imaptr, "colorspace_settings");
if (compact == 0) {
if (ima->source != IMA_SRC_GENERATED) {
if (image_has_alpha(ima, iuser)) {
uiLayout *sub = uiLayoutColumn(col, false);
uiItemR(sub, &imaptr, "alpha_mode", 0, IFACE_("Alpha"), ICON_NONE);
bool is_data = IMB_colormanagement_space_name_is_data(ima->colorspace_settings.name);
uiLayoutSetActive(sub, !is_data);
}
}
uiItemR(col, &imaptr, "use_view_as_render", 0, NULL, ICON_NONE);
}
}
UI_block_funcN_set(block, NULL, NULL, NULL);
}
void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, bool color_management)
@@ -1260,21 +1198,83 @@ void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser
void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser)
{
Scene *scene = CTX_data_scene(C);
ImBuf *ibuf;
char str[MAX_IMAGE_INFO_LEN];
void *lock;
if (!ima || !iuser) {
if (ima == NULL || iuser == NULL) {
return;
}
ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
/* Acquire image buffer. */
void *lock;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
uiLayout *col = uiLayoutColumn(layout, true);
if (ibuf == NULL) {
uiItemL(col, IFACE_("Can't Load Image"), ICON_NONE);
}
else {
char str[MAX_IMAGE_INFO_LEN] = {0};
const int len = MAX_IMAGE_INFO_LEN;
int ofs = 0;
ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_("%d x %d, "), ibuf->x, ibuf->y);
if (ibuf->rect_float) {
if (ibuf->channels != 4) {
ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_("%d float channel(s)"), ibuf->channels);
}
else if (ibuf->planes == R_IMF_PLANES_RGBA) {
ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA float"), len - ofs);
}
else {
ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB float"), len - ofs);
}
}
else {
if (ibuf->planes == R_IMF_PLANES_RGBA) {
ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA byte"), len - ofs);
}
else {
ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB byte"), len - ofs);
}
}
if (ibuf->zbuf || ibuf->zbuf_float) {
ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" + Z"), len - ofs);
}
uiItemL(col, str, ICON_NONE);
}
/* Frame number, even if we can't load the image. */
if (ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
/* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */
Scene *scene = CTX_data_scene(C);
const int framenr = BKE_image_user_frame_get(iuser, CFRA, NULL);
char str[MAX_IMAGE_INFO_LEN];
int duration = 0;
if (ima->source == IMA_SRC_MOVIE && BKE_image_has_anim(ima)) {
duration = IMB_anim_get_duration(((ImageAnim *)ima->anims.first)->anim, IMB_TC_RECORD_RUN);
}
if (duration > 0) {
/* Movie duration */
BLI_snprintf(str, MAX_IMAGE_INFO_LEN, IFACE_("Frame %d / %d"), framenr, duration);
}
else if (ima->source == IMA_SRC_SEQUENCE && ibuf) {
/* Image sequence frame number + filename */
const char *filename = BLI_last_slash(ibuf->name);
filename = (filename == NULL) ? ibuf->name : filename + 1;
BLI_snprintf(str, MAX_IMAGE_INFO_LEN, IFACE_("Frame %d: %s"), framenr, filename);
}
else {
/* Frame number */
BLI_snprintf(str, MAX_IMAGE_INFO_LEN, IFACE_("Frame %d"), framenr);
}
uiItemL(col, str, ICON_NONE);
}
BKE_image_user_frame_calc(iuser, (int)scene->r.cfra);
image_info(scene, iuser, ima, ibuf, str, MAX_IMAGE_INFO_LEN);
BKE_image_release_ibuf(ima, ibuf, lock);
uiItemL(layout, str, ICON_NONE);
}
#undef MAX_IMAGE_INFO_LEN