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 (9b099c8612).

Thanks to Matias Mendiola (@mendio) for helping to develop the layout
changes.

Differential Revision: https://developer.blender.org/D7985
This commit is contained in:
Hans Goudey 2020-06-19 15:07:13 -04:00
parent 702e00f910
commit bb4cef71ee
Notes: blender-bot 2023-02-14 04:40:22 +01:00
Referenced by commit 5b9bb688e7, UI: ShaderFX: Manually add X/Z labels for rim lighting
27 changed files with 949 additions and 238 deletions

View File

@ -24,11 +24,11 @@ class ShaderFxButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "shaderfx"
bl_options = {'HIDE_HEADER'}
class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel):
bl_label = "Effects"
bl_options = {'HIDE_HEADER'}
# Unused: always show for now.
@ -39,122 +39,8 @@ class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
ob = context.object
layout.operator_menu_enum("object.shaderfx_add", "type")
for fx in ob.shader_effects:
box = layout.template_shaderfx(fx)
if box:
# match enum type to our functions, avoids a lookup table.
getattr(self, fx.type)(box, fx)
# the mt.type enum is (ab)used for a lookup on function names
# ...to avoid lengthy if statements
# so each type must have a function here.
def FX_BLUR(self, layout, fx):
layout.prop(fx, "use_dof_mode", text="Use Depth of Field")
layout.separator()
col = layout.column()
col.enabled = not fx.use_dof_mode
col.prop(fx, "size", text="Size")
col.separator()
col.prop(fx, "rotation")
layout.prop(fx, "samples", text="Samples")
def FX_COLORIZE(self, layout, fx):
layout.prop(fx, "mode", text="Mode")
if fx.mode == 'DUOTONE':
layout.prop(fx, "low_color", text="Low Color")
if fx.mode == 'CUSTOM':
layout.prop(fx, "low_color", text="Color")
if fx.mode == 'DUOTONE':
layout.prop(fx, "high_color", text="High Color")
layout.prop(fx, "factor")
def FX_WAVE(self, layout, fx):
row = layout.row(align=True)
row.prop(fx, "orientation", expand=True)
layout.separator()
layout.prop(fx, "amplitude")
layout.prop(fx, "period")
layout.prop(fx, "phase")
def FX_PIXEL(self, layout, fx):
layout.prop(fx, "size", text="Size")
def FX_RIM(self, layout, fx):
layout.prop(fx, "offset", text="Offset")
layout.prop(fx, "rim_color")
layout.prop(fx, "mask_color")
layout.prop(fx, "mode", text="Blend")
layout.prop(fx, "blur")
layout.prop(fx, "samples")
def FX_SHADOW(self, layout, fx):
layout.prop(fx, "offset", text="Offset")
layout.prop(fx, "shadow_color")
layout.prop(fx, "scale")
layout.prop(fx, "rotation")
layout.separator()
layout.prop(fx, "blur")
layout.prop(fx, "samples")
layout.separator()
layout.prop(fx, "use_object", text="Use Object as Pivot")
if fx.use_object:
row = layout.row()
row.prop(fx, "object", text="Object")
layout.separator()
layout.prop(fx, "use_wave", text="Use Wave Effect")
if fx.use_wave is True:
row = layout.row(align=True)
row.prop(fx, "orientation", expand=True)
layout.prop(fx, "amplitude")
layout.prop(fx, "period")
layout.prop(fx, "phase")
def FX_GLOW(self, layout, fx):
layout.prop(fx, "mode")
if fx.mode == 'LUMINANCE':
layout.prop(fx, "threshold")
else:
layout.prop(fx, "select_color")
layout.prop(fx, "glow_color")
layout.separator()
layout.prop(fx, "blend_mode", text="Blend")
layout.prop(fx, "opacity")
layout.prop(fx, "size")
layout.prop(fx, "rotation")
layout.prop(fx, "samples")
layout.prop(fx, "use_glow_under", text="Glow Under")
def FX_SWIRL(self, layout, fx):
layout.prop(fx, "object", text="Object")
layout.prop(fx, "radius")
layout.prop(fx, "angle")
def FX_FLIP(self, layout, fx):
layout.prop(fx, "flip_horizontal")
layout.prop(fx, "flip_vertical")
layout.template_shaderfx()
classes = (

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
}
}
}
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
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);
Panel *new_panel = UI_panel_add_instanced(sa, region, &region->panels, panel_idname, i);
if (new_panel != NULL) {
UI_panel_set_expand_from_list_data(C, new_panel);
}
}
}
else {
/* The expansion might have been changed elsewhere, so we still need to set it. */
LISTBASE_FOREACH (Panel *, panel, &region->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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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");

View File

@ -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];

View File

@ -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 */

View File

@ -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);

View File

@ -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
)

View File

@ -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,
};

View File

@ -23,11 +23,23 @@
#include <stdio.h>
#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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -23,11 +23,23 @@
#include <stdio.h>
#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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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 <string.h>
#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(&region_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(&region_type->paneltypes, panel_type);
return panel_type;
}
/** \} */

View File

@ -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__ */