From bb4cef71eeaf36aa61187d47b8a8ae06ba55f7c0 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 19 Jun 2020 15:07:13 -0400 Subject: UI: ShaderFx Drag and Drop, Layout Updates This patch implements the list panel system D7490 for grease pencil shader effects. It also moves their drawing to a callback in ShaderFxTypeInfo in line with the extensible architecture refactoring goal T75724. The implementation is basically exactly the same as for the modifier patch (9b099c86123fc82). Thanks to Matias Mendiola (@mendio) for helping to develop the layout changes. Differential Revision: https://developer.blender.org/D7985 --- source/blender/blenkernel/BKE_shader_fx.h | 7 + source/blender/blenkernel/intern/shader_fx.c | 20 +- source/blender/blenloader/intern/versioning_290.c | 15 ++ source/blender/editors/include/ED_object.h | 4 + source/blender/editors/include/UI_interface.h | 3 +- .../editors/interface/interface_templates.c | 141 +++-------- source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_ops.c | 1 + source/blender/editors/object/object_shader_fx.c | 86 +++++++ .../blender/editors/space_buttons/space_buttons.c | 10 + source/blender/makesdna/DNA_shader_fx_types.h | 5 +- source/blender/makesrna/intern/rna_shader_fx.c | 6 +- source/blender/makesrna/intern/rna_ui_api.c | 6 +- source/blender/shader_fx/CMakeLists.txt | 5 + source/blender/shader_fx/intern/FX_shader_blur.c | 40 +++ .../blender/shader_fx/intern/FX_shader_colorize.c | 47 +++- source/blender/shader_fx/intern/FX_shader_flip.c | 36 +++ source/blender/shader_fx/intern/FX_shader_glow.c | 48 ++++ source/blender/shader_fx/intern/FX_shader_light.c | 10 + source/blender/shader_fx/intern/FX_shader_pixel.c | 38 +++ source/blender/shader_fx/intern/FX_shader_rim.c | 49 ++++ source/blender/shader_fx/intern/FX_shader_shadow.c | 94 +++++++ source/blender/shader_fx/intern/FX_shader_swirl.c | 32 +++ source/blender/shader_fx/intern/FX_shader_wave.c | 35 ++- source/blender/shader_fx/intern/FX_ui_common.c | 272 +++++++++++++++++++++ source/blender/shader_fx/intern/FX_ui_common.h | 56 +++++ 26 files changed, 946 insertions(+), 121 deletions(-) create mode 100644 source/blender/shader_fx/intern/FX_ui_common.c create mode 100644 source/blender/shader_fx/intern/FX_ui_common.h (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_shader_fx.h b/source/blender/blenkernel/BKE_shader_fx.h index bdc782a606e..31e14c6c884 100644 --- a/source/blender/blenkernel/BKE_shader_fx.h +++ b/source/blender/blenkernel/BKE_shader_fx.h @@ -28,6 +28,7 @@ extern "C" { #endif +struct ARegionType; struct ID; struct ListBase; struct ModifierUpdateDepsgraphContext; @@ -157,11 +158,17 @@ typedef struct ShaderFxTypeInfo { struct Object *ob, ShaderFxIDWalkFunc walk, void *userData); + + /* Register the panel types for the effect's UI. */ + void (*panelRegister)(struct ARegionType *region_type); } ShaderFxTypeInfo; +#define SHADERFX_TYPE_PANEL_PREFIX "FX_PT_" + /* Initialize global data (type info and some common global storages). */ void BKE_shaderfx_init(void); +void BKE_shaderfxType_panel_id(ShaderFxType type, char *panel_id); const ShaderFxTypeInfo *BKE_shaderfx_get_info(ShaderFxType type); struct ShaderFxData *BKE_shaderfx_new(int type); void BKE_shaderfx_free_ex(struct ShaderFxData *fx, const int flag); diff --git a/source/blender/blenkernel/intern/shader_fx.c b/source/blender/blenkernel/intern/shader_fx.c index 0ad61de1ff2..2923298c5d5 100644 --- a/source/blender/blenkernel/intern/shader_fx.c +++ b/source/blender/blenkernel/intern/shader_fx.c @@ -82,8 +82,9 @@ ShaderFxData *BKE_shaderfx_new(int type) BLI_strncpy(fx->name, DATA_(fxi->name), sizeof(fx->name)); fx->type = type; - fx->mode = eShaderFxMode_Realtime | eShaderFxMode_Render | eShaderFxMode_Expanded; + fx->mode = eShaderFxMode_Realtime | eShaderFxMode_Render; fx->flag = eShaderFxFlag_OverrideLibrary_Local; + fx->ui_expand_flag = 1; /* Expand only the parent panel by default. */ if (fxi->flags & eShaderFxTypeFlag_EnableInEditmode) { fx->mode |= eShaderFxMode_Editmode; @@ -156,7 +157,7 @@ bool BKE_shaderfx_depends_ontime(ShaderFxData *fx) const ShaderFxTypeInfo *BKE_shaderfx_get_info(ShaderFxType type) { /* type unsigned, no need to check < 0 */ - if (type < NUM_SHADER_FX_TYPES && shader_fx_types[type]->name[0] != '\0') { + if (type < NUM_SHADER_FX_TYPES && type > 0 && shader_fx_types[type]->name[0] != '\0') { return shader_fx_types[type]; } else { @@ -164,6 +165,20 @@ const ShaderFxTypeInfo *BKE_shaderfx_get_info(ShaderFxType type) } } +/** + * Get an effect's panel type, which was defined in the #panelRegister callback. + * + * \note ShaderFx panel types are assumed to be named with the struct name field concatenated to + * the defined prefix. + */ +void BKE_shaderfxType_panel_id(ShaderFxType type, char *r_idname) +{ + const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(type); + + strcpy(r_idname, SHADERFX_TYPE_PANEL_PREFIX); + strcat(r_idname, fxi->name); +} + void BKE_shaderfx_copydata_generic(const ShaderFxData *fx_src, ShaderFxData *fx_dst) { const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx_src->type); @@ -198,6 +213,7 @@ void BKE_shaderfx_copydata_ex(ShaderFxData *fx, ShaderFxData *target, const int target->mode = fx->mode; target->flag = fx->flag; + target->ui_expand_flag = fx->ui_expand_flag; if (fxi->copyData) { fxi->copyData(fx, target); diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index 00c73ebe9a7..bf4ed270e33 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -30,6 +30,7 @@ #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_screen_types.h" +#include "DNA_shader_fx_types.h" #include "BKE_collection.h" #include "BKE_colortools.h" @@ -317,5 +318,19 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + /* Transition to saving expansion for all of an effect's subpanels. */ + if (!DNA_struct_elem_find(fd->filesdna, "ShaderFxData", "short", "ui_expand_flag")) { + for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (ShaderFxData *, fx, &object->shader_fx) { + if (fx->mode & eShaderFxMode_Expanded_DEPRECATED) { + fx->ui_expand_flag = 1; + } + else { + fx->ui_expand_flag = 0; + } + } + } + } } } diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 0cc926987b2..73c58753531 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -453,6 +453,10 @@ int ED_object_shaderfx_move_down(struct ReportList *reports, int ED_object_shaderfx_move_up(struct ReportList *reports, struct Object *ob, struct ShaderFxData *fx); +bool ED_object_shaderfx_move_to_index(struct ReportList *reports, + struct Object *ob, + struct ShaderFxData *fx, + const int index); /* object_select.c */ void ED_object_select_linked_by_id(struct bContext *C, struct ID *id); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 8e9591c1963..bcbee51246e 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -2005,6 +2005,7 @@ void uiTemplatePathBuilder(uiLayout *layout, const char *text); void uiTemplateModifiers(uiLayout *layout, struct bContext *C); void uiTemplateGpencilModifiers(uiLayout *layout, struct bContext *C); +void uiTemplateShaderFx(uiLayout *layout, struct bContext *C); void uiTemplateConstraints(uiLayout *layout, struct bContext *C, bool use_bone_constraints); uiLayout *uiTemplateGpencilModifier(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr); @@ -2017,8 +2018,6 @@ void uiTemplateGpencilColorPreview(uiLayout *layout, float scale, int filter); -uiLayout *uiTemplateShaderFx(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr); - void uiTemplateOperatorRedoProperties(uiLayout *layout, const struct bContext *C); void uiTemplateConstraintHeader(uiLayout *layout, struct PointerRNA *ptr); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 56a71970f90..c3a432d6bcc 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2090,123 +2090,52 @@ void uiTemplateGpencilModifiers(uiLayout *UNUSED(layout), bContext *C) #define ERROR_LIBDATA_MESSAGE TIP_("Can't edit external library data") /* -------------------------------------------------------------------- */ -/** \name Grease Pencil Shader FX Template +/** \name ShaderFx Template + * + * Template for building the panel layout for the active object's grease pencil shader effects. * \{ */ -static uiLayout *gpencil_draw_shaderfx(uiLayout *layout, Object *ob, ShaderFxData *md) +/** + * Function with void * argument for #uiListPanelIDFromDataFunc. + */ +static void shaderfx_panel_id(void *fx_v, char *r_idname) { - const ShaderFxTypeInfo *mti = BKE_shaderfx_get_info(md->type); - PointerRNA ptr; - uiBlock *block; - uiLayout *box, *column, *row, *sub; - uiLayout *result = NULL; - - /* create RNA pointer */ - RNA_pointer_create(&ob->id, &RNA_ShaderFx, md, &ptr); - - column = uiLayoutColumn(layout, true); - uiLayoutSetContextPointer(column, "shaderfx", &ptr); - - /* rounded header ------------------------------------------------------------------- */ - box = uiLayoutBox(column); - - row = uiLayoutRow(box, false); - block = uiLayoutGetBlock(row); - - UI_block_emboss_set(block, UI_EMBOSS_NONE); - /* Open/Close ................................. */ - uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE); - - /* shader-type icon */ - uiItemL(row, "", RNA_struct_ui_icon(ptr.type)); - UI_block_emboss_set(block, UI_EMBOSS); - - /* effect name */ - if (mti->isDisabled && mti->isDisabled(md, 0)) { - uiLayoutSetRedAlert(row, true); - } - uiItemR(row, &ptr, "name", 0, "", ICON_NONE); - uiLayoutSetRedAlert(row, false); - - /* mode enabling buttons */ - UI_block_align_begin(block); - uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE); - uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE); - - if (mti->flags & eShaderFxTypeFlag_SupportsEditmode) { - sub = uiLayoutRow(row, true); - uiLayoutSetActive(sub, false); - uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE); - } - - UI_block_align_end(block); - - /* Up/Down + Delete ........................... */ - UI_block_align_begin(block); - uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_shaderfx_move_up"); - uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_shaderfx_move_down"); - UI_block_align_end(block); - - UI_block_emboss_set(block, UI_EMBOSS_NONE); - uiItemO(row, "", ICON_X, "OBJECT_OT_shaderfx_remove"); - UI_block_emboss_set(block, UI_EMBOSS); - - /* effect settings (under the header) --------------------------------------------------- */ - if (md->mode & eShaderFxMode_Expanded) { - /* apply/convert/copy */ - box = uiLayoutBox(column); - row = uiLayoutRow(box, false); - - /* only here obdata, the rest of effect is ob level */ - UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE); - - /* result is the layout block inside the box, - * that we return so that effect settings can be drawn */ - result = uiLayoutColumn(box, false); - block = uiLayoutAbsoluteBlock(box); - } - - /* error messages */ - if (md->error) { - box = uiLayoutBox(column); - row = uiLayoutRow(box, false); - uiItemL(row, md->error, ICON_ERROR); - } - - return result; + ShaderFxData *fx = (ShaderFxData *)fx_v; + BKE_shaderfxType_panel_id(fx->type, r_idname); } -uiLayout *uiTemplateShaderFx(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +/** + * Check if the shader effect panels don't match the data and rebuild the panels if so. + */ +void uiTemplateShaderFx(uiLayout *UNUSED(layout), bContext *C) { - Object *ob; - ShaderFxData *fx, *vfx; - int i; + ScrArea *sa = CTX_wm_area(C); + ARegion *region = CTX_wm_region(C); + Object *ob = get_context_object(C); + ListBase *shaderfx = &ob->shader_fx; - /* verify we have valid data */ - if (!RNA_struct_is_a(ptr->type, &RNA_ShaderFx)) { - RNA_warning("Expected shader fx on object"); - return NULL; - } + bool panels_match = UI_panel_list_matches_data(region, shaderfx, shaderfx_panel_id); - ob = (Object *)ptr->owner_id; - fx = ptr->data; + if (!panels_match) { + UI_panels_free_instanced(C, region); + ShaderFxData *fx = shaderfx->first; + for (int i = 0; fx; i++, fx = fx->next) { + char panel_idname[MAX_NAME]; + shaderfx_panel_id(fx, panel_idname); - if (!ob || !(GS(ob->id.name) == ID_OB)) { - RNA_warning("Expected shader fx on object"); - return NULL; + Panel *new_panel = UI_panel_add_instanced(sa, region, ®ion->panels, panel_idname, i); + if (new_panel != NULL) { + UI_panel_set_expand_from_list_data(C, new_panel); + } + } } - - UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE); - - /* find modifier and draw it */ - vfx = ob->shader_fx.first; - for (i = 0; vfx; i++, vfx = vfx->next) { - if (fx == vfx) { - return gpencil_draw_shaderfx(layout, ob, fx); + else { + /* The expansion might have been changed elsewhere, so we still need to set it. */ + LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { + if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED)) + UI_panel_set_expand_from_list_data(C, panel); } } - - return NULL; } /** \} */ @@ -2515,6 +2444,8 @@ void uiTemplateOperatorRedoProperties(uiLayout *layout, const bContext *C) /** \name Constraint Header Template * \{ */ +#define ERROR_LIBDATA_MESSAGE TIP_("Can't edit external library data") + static void constraint_active_func(bContext *UNUSED(C), void *ob_v, void *con_v) { ED_object_constraint_active_set(ob_v, con_v); diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 8feeb3b6067..3dbd1de123d 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -199,6 +199,7 @@ void OBJECT_OT_shaderfx_add(struct wmOperatorType *ot); void OBJECT_OT_shaderfx_remove(struct wmOperatorType *ot); void OBJECT_OT_shaderfx_move_up(struct wmOperatorType *ot); void OBJECT_OT_shaderfx_move_down(struct wmOperatorType *ot); +void OBJECT_OT_shaderfx_move_to_index(struct wmOperatorType *ot); /* object_constraint.c */ void OBJECT_OT_constraint_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 1060a808cfe..29058175e25 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -161,6 +161,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_shaderfx_remove); WM_operatortype_append(OBJECT_OT_shaderfx_move_up); WM_operatortype_append(OBJECT_OT_shaderfx_move_down); + WM_operatortype_append(OBJECT_OT_shaderfx_move_to_index); WM_operatortype_append(OBJECT_OT_correctivesmooth_bind); WM_operatortype_append(OBJECT_OT_meshdeform_bind); diff --git a/source/blender/editors/object/object_shader_fx.c b/source/blender/editors/object/object_shader_fx.c index 5db4a5a4f57..5abba70e008 100644 --- a/source/blender/editors/object/object_shader_fx.c +++ b/source/blender/editors/object/object_shader_fx.c @@ -200,6 +200,40 @@ int ED_object_shaderfx_move_down(ReportList *UNUSED(reports), Object *ob, Shader return 1; } +bool ED_object_shaderfx_move_to_index(ReportList *reports, + Object *ob, + ShaderFxData *fx, + const int index) +{ + BLI_assert(fx != NULL); + BLI_assert(index >= 0); + if (index >= BLI_listbase_count(&ob->shader_fx)) { + BKE_report(reports, RPT_WARNING, "Cannot move effect beyond the end of the stack"); + return false; + } + + int fx_index = BLI_findindex(&ob->shader_fx, fx); + BLI_assert(fx_index != -1); + if (fx_index < index) { + /* Move shaderfx down in list. */ + for (; fx_index < index; fx_index++) { + if (!ED_object_shaderfx_move_down(reports, ob, fx)) { + break; + } + } + } + else { + /* Move shaderfx up in list. */ + for (; fx_index > index; fx_index--) { + if (!ED_object_shaderfx_move_up(reports, ob, fx)) { + break; + } + } + } + + return true; +} + /************************ add effect operator *********************/ static int shaderfx_add_exec(bContext *C, wmOperator *op) @@ -487,3 +521,55 @@ void OBJECT_OT_shaderfx_move_down(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; edit_shaderfx_properties(ot); } + +/************************ move shaderfx to index operator *********************/ + +static bool shaderfx_move_to_index_poll(bContext *C) +{ + return edit_shaderfx_poll_generic(C, &RNA_ShaderFx, 0); +} + +static int shaderfx_move_to_index_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + ShaderFxData *fx = edit_shaderfx_property_get(op, ob, 0); + int index = RNA_int_get(op->ptr, "index"); + + if (!fx || !ED_object_shaderfx_move_to_index(op->reports, ob, fx, index)) { + return OPERATOR_CANCELLED; + } + + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int shaderfx_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (edit_shaderfx_invoke_properties(C, op)) { + return shaderfx_move_to_index_exec(C, op); + } + else { + return OPERATOR_CANCELLED; + } +} + +void OBJECT_OT_shaderfx_move_to_index(wmOperatorType *ot) +{ + ot->name = "Move Effect to Index"; + ot->idname = "OBJECT_OT_shaderfx_move_to_index"; + ot->description = + "Change the effect's position in the list so it evaluates after the set number of " + "others"; + + ot->invoke = shaderfx_move_to_index_invoke; + ot->exec = shaderfx_move_to_index_exec; + ot->poll = shaderfx_move_to_index_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + edit_shaderfx_properties(ot); + RNA_def_int( + ot->srna, "index", 0, 0, INT_MAX, "Index", "The index to move the effect to", 0, INT_MAX); +} diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 2cc9679dd3f..71b86996989 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -33,6 +33,7 @@ #include "BKE_gpencil_modifier.h" /* Types for registering panels. */ #include "BKE_modifier.h" #include "BKE_screen.h" +#include "BKE_shader_fx.h" #include "ED_screen.h" #include "ED_space_api.h" @@ -648,6 +649,15 @@ void ED_spacetype_buttons(void) mti->panelRegister(art); } } + for (int i = 0; i < NUM_SHADER_FX_TYPES; i++) { + if (i == eShaderFxType_Light_deprecated) { + continue; + } + const ShaderFxTypeInfo *fxti = BKE_shaderfx_get_info(i); + if (fxti != NULL && fxti->panelRegister != NULL) { + fxti->panelRegister(art); + } + } /* regions: header */ art = MEM_callocN(sizeof(ARegionType), "spacetype buttons region"); diff --git a/source/blender/makesdna/DNA_shader_fx_types.h b/source/blender/makesdna/DNA_shader_fx_types.h index 18a4e8655a3..2ccff2da993 100644 --- a/source/blender/makesdna/DNA_shader_fx_types.h +++ b/source/blender/makesdna/DNA_shader_fx_types.h @@ -50,7 +50,7 @@ typedef enum ShaderFxMode { eShaderFxMode_Realtime = (1 << 0), eShaderFxMode_Render = (1 << 1), eShaderFxMode_Editmode = (1 << 2), - eShaderFxMode_Expanded = (1 << 3), + eShaderFxMode_Expanded_DEPRECATED = (1 << 3), } ShaderFxMode; typedef enum { @@ -64,7 +64,8 @@ typedef struct ShaderFxData { int type, mode; int stackindex; short flag; - char _pad[2]; + /* Expansion for shader effect panels and subpanels. */ + short ui_expand_flag; /** MAX_NAME. */ char name[64]; diff --git a/source/blender/makesrna/intern/rna_shader_fx.c b/source/blender/makesrna/intern/rna_shader_fx.c index 71f767fa93b..d0565bb3aab 100644 --- a/source/blender/makesrna/intern/rna_shader_fx.c +++ b/source/blender/makesrna/intern/rna_shader_fx.c @@ -424,7 +424,7 @@ static void rna_def_shader_fx_shadow(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Offset", "Offset of the shadow"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); - prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "scale"); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_text(prop, "Scale", "Offset of the shadow"); @@ -681,9 +681,9 @@ void RNA_def_shader_fx(BlenderRNA *brna) prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE); RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", eShaderFxMode_Expanded); + RNA_def_property_boolean_sdna(prop, NULL, "ui_expand_flag", 0); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); - RNA_def_property_ui_text(prop, "Expanded", "Set effect expanded in the user interface"); + RNA_def_property_ui_text(prop, "Expanded", "Set effect expansion in the user interface"); RNA_def_property_ui_icon(prop, ICON_DISCLOSURE_TRI_RIGHT, 1); /* types */ diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 974daa51f99..906732c5fca 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -1229,11 +1229,7 @@ void RNA_api_ui_layout(StructRNA *srna) func = RNA_def_function(srna, "template_shaderfx", "uiTemplateShaderFx"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); - RNA_def_function_ui_description(func, "Generates the UI layout for shader effect"); - parm = RNA_def_pointer(func, "data", "ShaderFx", "", "Shader data"); - RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); - parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in"); - RNA_def_function_return(func, parm); + RNA_def_function_ui_description(func, "Generates the panels for the shader effect stack"); func = RNA_def_function(srna, "template_greasepencil_color", "uiTemplateGpencilColorPreview"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); diff --git a/source/blender/shader_fx/CMakeLists.txt b/source/blender/shader_fx/CMakeLists.txt index 9835c5c0588..740f7c126d1 100644 --- a/source/blender/shader_fx/CMakeLists.txt +++ b/source/blender/shader_fx/CMakeLists.txt @@ -24,12 +24,15 @@ set(INC intern ../blenfont ../blenkernel + ../blentranslation ../blenlib ../bmesh ../depsgraph + ../editors/include ../makesdna ../makesrna ../render/extern/include + ../windowmanager ../../../intern/eigen ../../../intern/guardedalloc ) @@ -40,6 +43,7 @@ set(INC_SYS set(SRC intern/FX_shader_util.h + intern/FX_ui_common.c intern/FX_shader_blur.c intern/FX_shader_colorize.c @@ -52,6 +56,7 @@ set(SRC intern/FX_shader_util.c intern/FX_shader_wave.c + intern/FX_ui_common.h FX_shader_types.h ) diff --git a/source/blender/shader_fx/intern/FX_shader_blur.c b/source/blender/shader_fx/intern/FX_shader_blur.c index 8881f147af8..8e3e7588818 100644 --- a/source/blender/shader_fx/intern/FX_shader_blur.c +++ b/source/blender/shader_fx/intern/FX_shader_blur.c @@ -26,7 +26,20 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLT_translation.h" + +#include "BKE_context.h" +#include "BKE_screen.h" + +#include "DNA_screen_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" + #include "FX_shader_types.h" +#include "FX_ui_common.h" static void initData(ShaderFxData *fx) { @@ -41,6 +54,32 @@ static void copyData(const ShaderFxData *md, ShaderFxData *target) BKE_shaderfx_copydata_generic(md, target); } +static void panel_draw(const bContext *C, Panel *panel) +{ + uiLayout *col; + uiLayout *layout = panel->layout; + + PointerRNA ptr; + shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr); + + uiLayoutSetPropSep(layout, true); + + uiItemR(layout, &ptr, "samples", 0, NULL, ICON_NONE); + + uiItemR(layout, &ptr, "use_dof_mode", 0, IFACE_("Use Depth of Field"), ICON_NONE); + col = uiLayoutColumn(layout, false); + uiLayoutSetActive(col, !RNA_boolean_get(&ptr, "use_dof_mode")); + uiItemR(col, &ptr, "size", 0, NULL, ICON_NONE); + uiItemR(col, &ptr, "rotation", 0, NULL, ICON_NONE); + + shaderfx_panel_end(layout, &ptr); +} + +static void panelRegister(ARegionType *region_type) +{ + shaderfx_panel_register(region_type, eShaderFxType_Blur, panel_draw); +} + ShaderFxTypeInfo shaderfx_Type_Blur = { /* name */ "Blur", /* structName */ "BlurShaderFxData", @@ -57,4 +96,5 @@ ShaderFxTypeInfo shaderfx_Type_Blur = { /* dependsOnTime */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* panelRegister */ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_colorize.c b/source/blender/shader_fx/intern/FX_shader_colorize.c index 5fea2cd0ff8..969171332fa 100644 --- a/source/blender/shader_fx/intern/FX_shader_colorize.c +++ b/source/blender/shader_fx/intern/FX_shader_colorize.c @@ -23,11 +23,23 @@ #include -#include "DNA_shader_fx_types.h" +#include "BKE_context.h" +#include "BKE_screen.h" #include "BLI_utildefines.h" +#include "BLT_translation.h" + +#include "DNA_screen_types.h" +#include "DNA_shader_fx_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" + #include "FX_shader_types.h" +#include "FX_ui_common.h" static void initData(ShaderFxData *fx) { @@ -43,6 +55,38 @@ static void copyData(const ShaderFxData *md, ShaderFxData *target) BKE_shaderfx_copydata_generic(md, target); } +static void panel_draw(const bContext *C, Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA ptr; + shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr); + + int mode = RNA_enum_get(&ptr, "mode"); + + uiLayoutSetPropSep(layout, true); + + uiItemR(layout, &ptr, "mode", 0, NULL, ICON_NONE); + + if (ELEM(mode, eShaderFxColorizeMode_Custom, eShaderFxColorizeMode_Duotone)) { + const char *text = (mode == eShaderFxColorizeMode_Duotone) ? IFACE_("Low Color") : + IFACE_("Color"); + uiItemR(layout, &ptr, "low_color", 0, text, ICON_NONE); + } + if (mode == eShaderFxColorizeMode_Duotone) { + uiItemR(layout, &ptr, "high_color", 0, NULL, ICON_NONE); + } + + uiItemR(layout, &ptr, "factor", 0, NULL, ICON_NONE); + + shaderfx_panel_end(layout, &ptr); +} + +static void panelRegister(ARegionType *region_type) +{ + shaderfx_panel_register(region_type, eShaderFxType_Colorize, panel_draw); +} + ShaderFxTypeInfo shaderfx_Type_Colorize = { /* name */ "Colorize", /* structName */ "ColorizeShaderFxData", @@ -59,4 +103,5 @@ ShaderFxTypeInfo shaderfx_Type_Colorize = { /* dependsOnTime */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* panelRegister */ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_flip.c b/source/blender/shader_fx/intern/FX_shader_flip.c index b915fb8e591..325d2c2608f 100644 --- a/source/blender/shader_fx/intern/FX_shader_flip.c +++ b/source/blender/shader_fx/intern/FX_shader_flip.c @@ -26,10 +26,22 @@ #include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" #include "BLI_utildefines.h" +#include "BLT_translation.h" + +#include "BKE_context.h" +#include "BKE_screen.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" + #include "FX_shader_types.h" +#include "FX_ui_common.h" static void initData(ShaderFxData *fx) { @@ -42,6 +54,29 @@ static void copyData(const ShaderFxData *md, ShaderFxData *target) BKE_shaderfx_copydata_generic(md, target); } +static void panel_draw(const bContext *C, Panel *panel) +{ + uiLayout *row; + uiLayout *layout = panel->layout; + int toggles_flag = UI_ITEM_R_TOGGLE | UI_ITEM_R_FORCE_BLANK_DECORATE; + + PointerRNA ptr; + shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr); + + uiLayoutSetPropSep(layout, true); + + row = uiLayoutRowWithHeading(layout, true, IFACE_("Axis")); + uiItemR(row, &ptr, "flip_horizontal", toggles_flag, NULL, ICON_NONE); + uiItemR(row, &ptr, "flip_vertical", toggles_flag, NULL, ICON_NONE); + + shaderfx_panel_end(layout, &ptr); +} + +static void panelRegister(ARegionType *region_type) +{ + shaderfx_panel_register(region_type, eShaderFxType_Flip, panel_draw); +} + ShaderFxTypeInfo shaderfx_Type_Flip = { /* name */ "Flip", /* structName */ "FlipShaderFxData", @@ -58,4 +93,5 @@ ShaderFxTypeInfo shaderfx_Type_Flip = { /* dependsOnTime */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* panelRegister */ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_glow.c b/source/blender/shader_fx/intern/FX_shader_glow.c index 1194e95ce79..4398fdc13bb 100644 --- a/source/blender/shader_fx/intern/FX_shader_glow.c +++ b/source/blender/shader_fx/intern/FX_shader_glow.c @@ -26,14 +26,23 @@ #include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BKE_context.h" #include "BKE_modifier.h" +#include "BKE_screen.h" #include "BKE_shader_fx.h" +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" + #include "FX_shader_types.h" +#include "FX_ui_common.h" static void initData(ShaderFxData *md) { @@ -50,6 +59,44 @@ static void copyData(const ShaderFxData *md, ShaderFxData *target) BKE_shaderfx_copydata_generic(md, target); } +static void panel_draw(const bContext *C, Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA ptr; + shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr); + + int mode = RNA_enum_get(&ptr, "mode"); + + uiLayoutSetPropSep(layout, true); + + uiItemR(layout, &ptr, "mode", 0, NULL, ICON_NONE); + + if (mode == eShaderFxGlowMode_Luminance) { + uiItemR(layout, &ptr, "threshold", 0, NULL, ICON_NONE); + } + else { + uiItemR(layout, &ptr, "select_color", 0, NULL, ICON_NONE); + } + uiItemR(layout, &ptr, "glow_color", 0, NULL, ICON_NONE); + + uiItemS(layout); + + uiItemR(layout, &ptr, "blend_mode", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "opacity", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "size", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "rotation", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "samples", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "use_glow_under", 0, NULL, ICON_NONE); + + shaderfx_panel_end(layout, &ptr); +} + +static void panelRegister(ARegionType *region_type) +{ + shaderfx_panel_register(region_type, eShaderFxType_Glow, panel_draw); +} + ShaderFxTypeInfo shaderfx_Type_Glow = { /* name */ "Glow", /* structName */ "GlowShaderFxData", @@ -66,4 +113,5 @@ ShaderFxTypeInfo shaderfx_Type_Glow = { /* dependsOnTime */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* panelRegister */ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_light.c b/source/blender/shader_fx/intern/FX_shader_light.c index 17d2f518d44..2fd93bff8aa 100644 --- a/source/blender/shader_fx/intern/FX_shader_light.c +++ b/source/blender/shader_fx/intern/FX_shader_light.c @@ -26,14 +26,23 @@ #include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" #include "BLI_utildefines.h" +#include "BKE_context.h" #include "BKE_lib_query.h" #include "BKE_modifier.h" +#include "BKE_screen.h" #include "BKE_shader_fx.h" +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" + #include "FX_shader_types.h" +#include "FX_ui_common.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -93,4 +102,5 @@ ShaderFxTypeInfo shaderfx_Type_Light = { /* dependsOnTime */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* panelRegister */ NULL, }; diff --git a/source/blender/shader_fx/intern/FX_shader_pixel.c b/source/blender/shader_fx/intern/FX_shader_pixel.c index 04bf9ae5b6d..b22dae1064d 100644 --- a/source/blender/shader_fx/intern/FX_shader_pixel.c +++ b/source/blender/shader_fx/intern/FX_shader_pixel.c @@ -25,7 +25,20 @@ #include "BLI_utildefines.h" +#include "BLT_translation.h" + +#include "BKE_context.h" +#include "BKE_screen.h" + +#include "DNA_screen_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" + #include "FX_shader_types.h" +#include "FX_ui_common.h" static void initData(ShaderFxData *fx) { @@ -39,6 +52,30 @@ static void copyData(const ShaderFxData *md, ShaderFxData *target) BKE_shaderfx_copydata_generic(md, target); } +static void panel_draw(const bContext *C, Panel *panel) +{ + uiLayout *col; + uiLayout *layout = panel->layout; + + PointerRNA ptr; + shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr); + + uiLayoutSetPropSep(layout, true); + + /* Add the X, Y labels manually because size is a #PROP_PIXEL. */ + col = uiLayoutColumn(layout, true); + PropertyRNA *prop = RNA_struct_find_property(&ptr, "size"); + uiItemFullR(col, &ptr, prop, 0, 0, 0, IFACE_("Size X"), ICON_NONE); + uiItemFullR(col, &ptr, prop, 1, 0, 0, IFACE_("Y"), ICON_NONE); + + shaderfx_panel_end(layout, &ptr); +} + +static void panelRegister(ARegionType *region_type) +{ + shaderfx_panel_register(region_type, eShaderFxType_Pixel, panel_draw); +} + ShaderFxTypeInfo shaderfx_Type_Pixel = { /* name */ "Pixelate", /* structName */ "PixelShaderFxData", @@ -55,4 +92,5 @@ ShaderFxTypeInfo shaderfx_Type_Pixel = { /* dependsOnTime */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* panelRegister */ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_rim.c b/source/blender/shader_fx/intern/FX_shader_rim.c index 16c6a6716a0..4b3ce0109c3 100644 --- a/source/blender/shader_fx/intern/FX_shader_rim.c +++ b/source/blender/shader_fx/intern/FX_shader_rim.c @@ -23,11 +23,23 @@ #include +#include "DNA_screen_types.h" #include "DNA_shader_fx_types.h" #include "BLI_utildefines.h" +#include "BLT_translation.h" + +#include "BKE_context.h" +#include "BKE_screen.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" + #include "FX_shader_types.h" +#include "FX_ui_common.h" static void initData(ShaderFxData *fx) { @@ -46,6 +58,42 @@ static void copyData(const ShaderFxData *md, ShaderFxData *target) BKE_shaderfx_copydata_generic(md, target); } +static void panel_draw(const bContext *C, Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA ptr; + shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr); + + uiLayoutSetPropSep(layout, true); + + uiItemR(layout, &ptr, "rim_color", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "mask_color", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "mode", 0, IFACE_("Blend"), ICON_NONE); + uiItemR(layout, &ptr, "offset", 0, NULL, ICON_NONE); + + shaderfx_panel_end(layout, &ptr); +} + +static void blur_panel_draw(const bContext *C, Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA ptr; + shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr); + + uiLayoutSetPropSep(layout, true); + + uiItemR(layout, &ptr, "blur", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "samples", 0, NULL, ICON_NONE); +} + +static void panelRegister(ARegionType *region_type) +{ + PanelType *panel_type = shaderfx_panel_register(region_type, eShaderFxType_Rim, panel_draw); + shaderfx_subpanel_register(region_type, "blur", "Blur", NULL, blur_panel_draw, panel_type); +} + ShaderFxTypeInfo shaderfx_Type_Rim = { /* name */ "Rim", /* structName */ "RimShaderFxData", @@ -62,4 +110,5 @@ ShaderFxTypeInfo shaderfx_Type_Rim = { /* dependsOnTime */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* panelRegister */ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_shadow.c b/source/blender/shader_fx/intern/FX_shader_shadow.c index dcf66ec89e0..11690d2cca0 100644 --- a/source/blender/shader_fx/intern/FX_shader_shadow.c +++ b/source/blender/shader_fx/intern/FX_shader_shadow.c @@ -26,14 +26,25 @@ #include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" #include "BLI_utildefines.h" +#include "BLT_translation.h" + +#include "BKE_context.h" #include "BKE_lib_query.h" #include "BKE_modifier.h" +#include "BKE_screen.h" #include "BKE_shader_fx.h" +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" + #include "FX_shader_types.h" +#include "FX_ui_common.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -88,6 +99,88 @@ static void foreachObjectLink(ShaderFxData *fx, walk(userData, ob, &fxd->object, IDWALK_CB_NOP); } +static void panel_draw(const bContext *C, Panel *panel) +{ + uiLayout *row, *col; + uiLayout *layout = panel->layout; + + PointerRNA ptr; + shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr); + + uiLayoutSetPropSep(layout, true); + + uiItemR(layout, &ptr, "shadow_color", 0, NULL, ICON_NONE); + + /* Add the X, Y labels manually because size is a #PROP_PIXEL. */ + col = uiLayoutColumn(layout, true); + PropertyRNA *prop = RNA_struct_find_property(&ptr, "offset"); + uiItemFullR(col, &ptr, prop, 0, 0, 0, IFACE_("Offset X"), ICON_NONE); + uiItemFullR(col, &ptr, prop, 1, 0, 0, IFACE_("Y"), ICON_NONE); + + uiItemR(layout, &ptr, "scale", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "rotation", 0, NULL, ICON_NONE); + + row = uiLayoutRowWithHeading(layout, true, IFACE_("Object Pivot")); + uiItemR(row, &ptr, "use_object", 0, "", ICON_NONE); + uiItemR(row, &ptr, "object", 0, "", ICON_NONE); + + shaderfx_panel_end(layout, &ptr); +} + +static void blur_panel_draw(const bContext *C, Panel *panel) +{ + uiLayout *col; + uiLayout *layout = panel->layout; + + PointerRNA ptr; + shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr); + + uiLayoutSetPropSep(layout, true); + + /* Add the X, Y labels manually because size is a #PROP_PIXEL. */ + col = uiLayoutColumn(layout, true); + PropertyRNA *prop = RNA_struct_find_property(&ptr, "blur"); + uiItemFullR(col, &ptr, prop, 0, 0, 0, IFACE_("Blur X"), ICON_NONE); + uiItemFullR(col, &ptr, prop, 1, 0, 0, IFACE_("Y"), ICON_NONE); + + uiItemR(layout, &ptr, "samples", 0, NULL, ICON_NONE); +} + +static void wave_header_draw(const bContext *C, Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA ptr; + shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr); + + uiItemR(layout, &ptr, "use_wave", 0, IFACE_("Wave Effect"), ICON_NONE); +} + +static void wave_panel_draw(const bContext *C, Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA ptr; + shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr); + + uiLayoutSetPropSep(layout, true); + + uiLayoutSetActive(layout, RNA_boolean_get(&ptr, "use_wave")); + + uiItemR(layout, &ptr, "orientation", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemR(layout, &ptr, "amplitude", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "period", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "phase", 0, NULL, ICON_NONE); +} + +static void panelRegister(ARegionType *region_type) +{ + PanelType *panel_type = shaderfx_panel_register(region_type, eShaderFxType_Shadow, panel_draw); + shaderfx_subpanel_register(region_type, "blur", "Blur", NULL, blur_panel_draw, panel_type); + shaderfx_subpanel_register( + region_type, "wave", "", wave_header_draw, wave_panel_draw, panel_type); +} + ShaderFxTypeInfo shaderfx_Type_Shadow = { /* name */ "Shadow", /* structName */ "ShadowShaderFxData", @@ -104,4 +197,5 @@ ShaderFxTypeInfo shaderfx_Type_Shadow = { /* dependsOnTime */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* panelRegister */ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_swirl.c b/source/blender/shader_fx/intern/FX_shader_swirl.c index 990b43748da..65e861fa46f 100644 --- a/source/blender/shader_fx/intern/FX_shader_swirl.c +++ b/source/blender/shader_fx/intern/FX_shader_swirl.c @@ -26,15 +26,24 @@ #include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" #include "BLI_math_base.h" #include "BLI_utildefines.h" +#include "BKE_context.h" #include "BKE_lib_query.h" #include "BKE_modifier.h" +#include "BKE_screen.h" #include "BKE_shader_fx.h" +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" + #include "FX_shader_types.h" +#include "FX_ui_common.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -77,6 +86,28 @@ static void foreachObjectLink(ShaderFxData *fx, walk(userData, ob, &fxd->object, IDWALK_CB_NOP); } +static void panel_draw(const bContext *C, Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA ptr; + PointerRNA ob_ptr; + shaderfx_panel_get_property_pointers(C, panel, &ob_ptr, &ptr); + + uiLayoutSetPropSep(layout, true); + + uiItemR(layout, &ptr, "object", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "radius", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "angle", 0, NULL, ICON_NONE); + + shaderfx_panel_end(layout, &ptr); +} + +static void panelRegister(ARegionType *region_type) +{ + shaderfx_panel_register(region_type, eShaderFxType_Swirl, panel_draw); +} + ShaderFxTypeInfo shaderfx_Type_Swirl = { /* name */ "Swirl", /* structName */ "SwirlShaderFxData", @@ -93,4 +124,5 @@ ShaderFxTypeInfo shaderfx_Type_Swirl = { /* dependsOnTime */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* panelRegister */ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_wave.c b/source/blender/shader_fx/intern/FX_shader_wave.c index 7dc72bcb669..3b8256edae3 100644 --- a/source/blender/shader_fx/intern/FX_shader_wave.c +++ b/source/blender/shader_fx/intern/FX_shader_wave.c @@ -26,10 +26,20 @@ #include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" + +#include "BKE_context.h" +#include "BKE_screen.h" #include "BLI_utildefines.h" +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" + #include "FX_shader_types.h" +#include "FX_ui_common.h" static void initData(ShaderFxData *fx) { @@ -45,8 +55,30 @@ static void copyData(const ShaderFxData *md, ShaderFxData *target) BKE_shaderfx_copydata_generic(md, target); } +static void panel_draw(const bContext *C, Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA ptr; + shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr); + + uiLayoutSetPropSep(layout, true); + + uiItemR(layout, &ptr, "orientation", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemR(layout, &ptr, "amplitude", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "period", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "phase", 0, NULL, ICON_NONE); + + shaderfx_panel_end(layout, &ptr); +} + +static void panelRegister(ARegionType *region_type) +{ + shaderfx_panel_register(region_type, eShaderFxType_Wave, panel_draw); +} + ShaderFxTypeInfo shaderfx_Type_Wave = { - /* name */ "Wave Distortion", + /* name */ "WaveDistortion", /* structName */ "WaveShaderFxData", /* structSize */ sizeof(WaveShaderFxData), /* type */ eShaderFxType_GpencilType, @@ -61,4 +93,5 @@ ShaderFxTypeInfo shaderfx_Type_Wave = { /* dependsOnTime */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* panelRegister */ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_ui_common.c b/source/blender/shader_fx/intern/FX_ui_common.c new file mode 100644 index 00000000000..e02074a92a8 --- /dev/null +++ b/source/blender/shader_fx/intern/FX_ui_common.c @@ -0,0 +1,272 @@ +/* This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup modifiers + */ + +#include + +#include "BLI_listbase.h" + +#include "MEM_guardedalloc.h" + +#include "BKE_context.h" +#include "BKE_object.h" +#include "BKE_screen.h" +#include "BKE_shader_fx.h" + +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_shader_fx_types.h" +#include "DNA_space_types.h" + +#include "ED_object.h" + +#include "BLT_translation.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "FX_ui_common.h" /* Self include */ + +static Object *get_context_object(const bContext *C) +{ + SpaceProperties *sbuts = CTX_wm_space_properties(C); + if (sbuts != NULL && (sbuts->pinid != NULL) && GS(sbuts->pinid->name) == ID_OB) { + return (Object *)sbuts->pinid; + } + else { + return CTX_data_active_object(C); + } +} + +/* -------------------------------------------------------------------- */ +/** \name Panel Drag and Drop, Expansion Saving + * \{ */ + +/** + * Move an effect to the index it's moved to after a drag and drop. + */ +static void shaderfx_reorder(bContext *C, Panel *panel, int new_index) +{ + Object *ob = get_context_object(C); + + ShaderFxData *fx = BLI_findlink(&ob->shader_fx, panel->runtime.list_index); + PointerRNA props_ptr; + wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_shaderfx_move_to_index", false); + WM_operator_properties_create_ptr(&props_ptr, ot); + RNA_string_set(&props_ptr, "shaderfx", fx->name); + RNA_int_set(&props_ptr, "index", new_index); + WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr); +} + +/** + * Get the expand flag from the active effect to use for the panel. + */ +static short get_shaderfx_expand_flag(const bContext *C, Panel *panel) +{ + Object *ob = get_context_object(C); + ShaderFxData *fx = BLI_findlink(&ob->shader_fx, panel->runtime.list_index); + return fx->ui_expand_flag; +} + +/** + * Save the expand flag for the panel and subpanels to the effect. + */ +static void set_shaderfx_expand_flag(const bContext *C, Panel *panel, short expand_flag) +{ + Object *ob = get_context_object(C); + ShaderFxData *fx = BLI_findlink(&ob->shader_fx, panel->runtime.list_index); + fx->ui_expand_flag = expand_flag; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name ShaderFx Panel Layouts + * \{ */ + +/** + * Draw shaderfx error message. + */ +void shaderfx_panel_end(uiLayout *layout, PointerRNA *ptr) +{ + ShaderFxData *fx = ptr->data; + if (fx->error) { + uiLayout *row = uiLayoutRow(layout, false); + uiItemL(row, IFACE_(fx->error), ICON_ERROR); + } +} + +/** + * Gets RNA pointers for the active object and the panel's shaderfx data. + */ +void shaderfx_panel_get_property_pointers(const bContext *C, + Panel *panel, + PointerRNA *r_ob_ptr, + PointerRNA *r_md_ptr) +{ + Object *ob = get_context_object(C); + ShaderFxData *md = BLI_findlink(&ob->shader_fx, panel->runtime.list_index); + + RNA_pointer_create(&ob->id, &RNA_ShaderFx, md, r_md_ptr); + + if (r_ob_ptr != NULL) { + RNA_pointer_create(&ob->id, &RNA_Object, ob, r_ob_ptr); + } + + uiLayoutSetContextPointer(panel->layout, "shaderfx", r_md_ptr); +} + +#define ERROR_LIBDATA_MESSAGE TIP_("External library data") + +static void shaderfx_panel_header(const bContext *C, Panel *panel) +{ + uiLayout *layout = panel->layout; + bool narrow_panel = (panel->sizex < UI_UNIT_X * 7 && panel->sizex != 0); + + PointerRNA ptr; + shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr); + Object *ob = get_context_object(C); + ShaderFxData *fx = (ShaderFxData *)ptr.data; + + const ShaderFxTypeInfo *fxti = BKE_shaderfx_get_info(fx->type); + + UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE); + + /* Effect type icon. */ + uiLayout *row = uiLayoutRow(layout, false); + if (fxti->isDisabled && fxti->isDisabled(fx, 0)) { + uiLayoutSetRedAlert(row, true); + } + uiItemL(row, "", RNA_struct_ui_icon(ptr.type)); + + /* Effect name. */ + row = uiLayoutRow(layout, true); + if (!narrow_panel) { + uiItemR(row, &ptr, "name", 0, "", ICON_NONE); + } + + /* Mode enabling buttons. */ + if (fxti->flags & eShaderFxTypeFlag_SupportsEditmode) { + uiLayout *sub = uiLayoutRow(row, true); + uiLayoutSetActive(sub, false); + uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE); + } + uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE); + uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE); + + row = uiLayoutRow(row, false); + uiLayoutSetEmboss(row, UI_EMBOSS_NONE); + uiItemO(row, "", ICON_X, "OBJECT_OT_shaderfx_remove"); + + /* Some padding so the X isn't too close to the drag icon. */ + uiItemS(layout); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name ShaderFx Registration Helpers + * \{ */ + +static bool shaderfx_ui_poll(const bContext *C, PanelType *UNUSED(pt)) +{ + Object *ob = get_context_object(C); + + return (ob != NULL) && (ob->type == OB_GPENCIL); +} + +/** + * Create a panel in the context's region + */ +PanelType *shaderfx_panel_register(ARegionType *region_type, ShaderFxType type, PanelDrawFn draw) +{ + + /* Get the name for the effect's panel. */ + char panel_idname[BKE_ST_MAXNAME]; + BKE_shaderfxType_panel_id(type, panel_idname); + + PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname); + + strcpy(panel_type->idname, panel_idname); + strcpy(panel_type->label, ""); + strcpy(panel_type->context, "shaderfx"); + strcpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); + + panel_type->draw_header = shaderfx_panel_header; + panel_type->draw = draw; + panel_type->poll = shaderfx_ui_poll; + + /* Give the panel the special flag that says it was built here and corresponds to a + * shader effect rather than a PanelType. */ + panel_type->flag = PNL_LAYOUT_HEADER_EXPAND | PNL_DRAW_BOX | PNL_INSTANCED; + panel_type->reorder = shaderfx_reorder; + panel_type->get_list_data_expand_flag = get_shaderfx_expand_flag; + panel_type->set_list_data_expand_flag = set_shaderfx_expand_flag; + + BLI_addtail(®ion_type->paneltypes, panel_type); + + return panel_type; +} + +/** + * Add a child panel to the parent. + * + * \note To create the panel type's idname, it appends the \a name argument to the \a parent's + * idname. + */ +PanelType *shaderfx_subpanel_register(ARegionType *region_type, + const char *name, + const char *label, + PanelDrawFn draw_header, + PanelDrawFn draw, + PanelType *parent) +{ + /* Create the subpanel's ID name. */ + char panel_idname[BKE_ST_MAXNAME]; + strcpy(panel_idname, parent->idname); + strcat(panel_idname, "_"); + strcat(panel_idname, name); + + PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname); + + strcpy(panel_type->idname, panel_idname); + strcpy(panel_type->label, label); + strcpy(panel_type->context, "shaderfx"); + strcpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); + + panel_type->draw_header = draw_header; + panel_type->draw = draw; + panel_type->poll = shaderfx_ui_poll; + panel_type->flag = (PNL_DEFAULT_CLOSED | PNL_DRAW_BOX); + + BLI_assert(parent != NULL); + strcpy(panel_type->parent_id, parent->idname); + panel_type->parent = parent; + BLI_addtail(&parent->children, BLI_genericNodeN(panel_type)); + BLI_addtail(®ion_type->paneltypes, panel_type); + + return panel_type; +} + +/** \} */ diff --git a/source/blender/shader_fx/intern/FX_ui_common.h b/source/blender/shader_fx/intern/FX_ui_common.h new file mode 100644 index 00000000000..877855b98e4 --- /dev/null +++ b/source/blender/shader_fx/intern/FX_ui_common.h @@ -0,0 +1,56 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup modifiers + */ + +#ifndef __FX_UI_COMMON_H__ +#define __FX_UI_COMMON_H__ + +#include "FX_shader_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct ARegionType; +struct bContext; +struct PanelType; +struct uiLayout; +typedef void (*PanelDrawFn)(const bContext *, Panel *); + +void shaderfx_panel_end(struct uiLayout *layout, PointerRNA *ptr); + +void shaderfx_panel_get_property_pointers(const bContext *C, + struct Panel *panel, + struct PointerRNA *r_ob_ptr, + struct PointerRNA *r_ptr); + +PanelType *shaderfx_panel_register(ARegionType *region_type, ShaderFxType type, PanelDrawFn draw); + +struct PanelType *shaderfx_subpanel_register(struct ARegionType *region_type, + const char *name, + const char *label, + PanelDrawFn draw_header, + PanelDrawFn draw, + struct PanelType *parent); + +#ifdef __cplusplus +} +#endif + +#endif /* __FX_UI_COMMON_H__ */ -- cgit v1.2.3