Blender  V2.93
MOD_gpencil_ui_common.c
Go to the documentation of this file.
1 /* This program is free software; you can redistribute it and/or
2  * modify it under the terms of the GNU General Public License
3  * as published by the Free Software Foundation; either version 2
4  * of the License, or (at your option) any later version.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software Foundation,
13  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14  */
15 
20 #include "BLI_listbase.h"
21 #include "BLI_string.h"
22 
23 #include "MEM_guardedalloc.h"
24 
25 #include "BKE_context.h"
26 #include "BKE_gpencil_modifier.h"
27 #include "BKE_material.h"
28 #include "BKE_screen.h"
29 
30 #include "DNA_material_types.h"
31 #include "DNA_object_types.h"
32 #include "DNA_screen_types.h"
33 
34 #include "ED_object.h"
35 
36 #include "BLT_translation.h"
37 
38 #include "UI_interface.h"
39 #include "UI_resources.h"
40 
41 #include "RNA_access.h"
42 
43 #include "WM_api.h"
44 #include "WM_types.h"
45 
46 #include "MOD_gpencil_ui_common.h" /* Self include */
47 
52 {
54 
55  return (ob != NULL) && (ob->type == OB_GPENCIL);
56 }
57 
58 /* -------------------------------------------------------------------- */
65 static void gpencil_modifier_reorder(bContext *C, Panel *panel, int new_index)
66 {
67  PointerRNA *md_ptr = UI_panel_custom_data_get(panel);
69 
70  PointerRNA props_ptr;
71  wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_gpencil_modifier_move_to_index", false);
73  RNA_string_set(&props_ptr, "modifier", md->name);
74  RNA_int_set(&props_ptr, "index", new_index);
76  WM_operator_properties_free(&props_ptr);
77 }
78 
80 {
81  PointerRNA *md_ptr = UI_panel_custom_data_get(panel);
83  return md->ui_expand_flag;
84 }
85 
87  Panel *panel,
88  short expand_flag)
89 {
90  PointerRNA *md_ptr = UI_panel_custom_data_get(panel);
92  md->ui_expand_flag = expand_flag;
93 }
94 
97 /* -------------------------------------------------------------------- */
101 void gpencil_modifier_masking_panel_draw(Panel *panel, bool use_material, bool use_vertex)
102 {
103  uiLayout *row, *col, *sub;
104  uiLayout *layout = panel->layout;
105 
106  PointerRNA ob_ptr;
108 
109  PointerRNA obj_data_ptr = RNA_pointer_get(&ob_ptr, "data");
110  bool has_layer = RNA_string_length(ptr, "layer") != 0;
111 
112  uiLayoutSetPropSep(layout, true);
113 
114  col = uiLayoutColumn(layout, true);
115  row = uiLayoutRow(col, true);
116  uiItemPointerR(row, ptr, "layer", &obj_data_ptr, "layers", NULL, ICON_GREASEPENCIL);
117  sub = uiLayoutRow(row, true);
118  uiLayoutSetActive(sub, has_layer);
119  uiLayoutSetPropDecorate(sub, false);
120  uiItemR(sub, ptr, "invert_layers", 0, "", ICON_ARROW_LEFTRIGHT);
121 
122  row = uiLayoutRow(col, true);
123  uiItemR(row, ptr, "layer_pass", 0, NULL, ICON_NONE);
124  sub = uiLayoutRow(row, true);
125  uiLayoutSetActive(sub, RNA_int_get(ptr, "layer_pass") != 0);
126  uiLayoutSetPropDecorate(sub, false);
127  uiItemR(sub, ptr, "invert_layer_pass", 0, "", ICON_ARROW_LEFTRIGHT);
128 
129  if (use_material) {
130  PointerRNA material_ptr = RNA_pointer_get(ptr, "material");
131  bool has_material = !RNA_pointer_is_null(&material_ptr);
132 
133  /* Because the Gpencil modifier material property used to be a string in an earlier version of
134  * Blender, we need to check if the material is valid and display it differently if so. */
135  bool valid = false;
136  {
137  if (!has_material) {
138  valid = true;
139  }
140  else {
141  Material *current_material = material_ptr.data;
142  Object *ob = ob_ptr.data;
143  for (int i = 0; i <= ob->totcol; i++) {
144  Material *mat = BKE_object_material_get(ob, i);
145  if (mat == current_material) {
146  valid = true;
147  break;
148  }
149  }
150  }
151  }
152 
153  col = uiLayoutColumn(layout, true);
154  row = uiLayoutRow(col, true);
155  uiLayoutSetRedAlert(row, !valid);
156  uiItemPointerR(row,
157  ptr,
158  "material",
159  &obj_data_ptr,
160  "materials",
161  NULL,
162  valid ? ICON_SHADING_TEXTURE : ICON_ERROR);
163  sub = uiLayoutRow(row, true);
164  uiLayoutSetActive(sub, has_material);
165  uiLayoutSetPropDecorate(sub, false);
166  uiItemR(sub, ptr, "invert_materials", 0, "", ICON_ARROW_LEFTRIGHT);
167 
168  row = uiLayoutRow(col, true);
169  uiItemR(row, ptr, "pass_index", 0, NULL, ICON_NONE);
170  sub = uiLayoutRow(row, true);
171  uiLayoutSetActive(sub, RNA_int_get(ptr, "pass_index") != 0);
172  uiLayoutSetPropDecorate(sub, false);
173  uiItemR(sub, ptr, "invert_material_pass", 0, "", ICON_ARROW_LEFTRIGHT);
174  }
175 
176  if (use_vertex) {
177  bool has_vertex_group = RNA_string_length(ptr, "vertex_group") != 0;
178 
179  row = uiLayoutRow(layout, true);
180  uiItemPointerR(row, ptr, "vertex_group", &ob_ptr, "vertex_groups", NULL, ICON_NONE);
181  sub = uiLayoutRow(row, true);
182  uiLayoutSetActive(sub, has_vertex_group);
183  uiLayoutSetPropDecorate(sub, false);
184  uiItemR(sub, ptr, "invert_vertex", 0, "", ICON_ARROW_LEFTRIGHT);
185  }
186 }
187 
189 {
190  uiLayout *layout = panel->layout;
191 
193 
194  uiItemR(layout, ptr, "use_custom_curve", 0, NULL, ICON_NONE);
195 }
196 
198 {
199  uiLayout *layout = panel->layout;
200 
202 
203  uiTemplateCurveMapping(layout, ptr, "curve", 0, false, false, false, false);
204 }
205 
210 {
212  if (md->error) {
213  uiLayout *row = uiLayoutRow(layout, false);
214  uiItemL(row, IFACE_(md->error), ICON_ERROR);
215  }
216 }
217 
221 #define ERROR_LIBDATA_MESSAGE TIP_("External library data")
223 {
226 
227  if (r_ob_ptr != NULL) {
229  }
230 
231  uiBlock *block = uiLayoutGetBlock(panel->layout);
232  UI_block_lock_clear(block);
234 
235  uiLayoutSetContextPointer(panel->layout, "modifier", ptr);
236 
237  return ptr;
238 }
239 
240 static void gpencil_modifier_ops_extra_draw(bContext *C, uiLayout *layout, void *md_v)
241 {
242  PointerRNA op_ptr;
243  uiLayout *row;
246 
247  PointerRNA ptr;
250  uiLayoutSetContextPointer(layout, "modifier", &ptr);
252 
253  uiLayoutSetUnitsX(layout, 4.0f);
254 
255  /* Apply. */
256  if (!(mti->flags & eGpencilModifierTypeFlag_NoApply)) {
257  uiItemO(layout,
259  ICON_CHECKMARK,
260  "OBJECT_OT_gpencil_modifier_apply");
261  }
262 
263  /* Duplicate. */
264  uiItemO(layout,
266  ICON_DUPLICATE,
267  "OBJECT_OT_gpencil_modifier_copy");
268 
269  uiItemO(layout,
270  CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy to Selected"),
271  0,
272  "OBJECT_OT_gpencil_modifier_copy_to_selected");
273 
274  uiItemS(layout);
275 
276  /* Move to first. */
277  row = uiLayoutColumn(layout, false);
278  uiItemFullO(row,
279  "OBJECT_OT_gpencil_modifier_move_to_index",
280  IFACE_("Move to First"),
281  ICON_TRIA_UP,
282  NULL,
284  0,
285  &op_ptr);
286  RNA_int_set(&op_ptr, "index", 0);
287  if (!md->prev) {
288  uiLayoutSetEnabled(row, false);
289  }
290 
291  /* Move to last. */
292  row = uiLayoutColumn(layout, false);
293  uiItemFullO(row,
294  "OBJECT_OT_gpencil_modifier_move_to_index",
295  IFACE_("Move to Last"),
296  ICON_TRIA_DOWN,
297  NULL,
299  0,
300  &op_ptr);
301  RNA_int_set(&op_ptr, "index", BLI_listbase_count(&ob->greasepencil_modifiers) - 1);
302  if (!md->next) {
303  uiLayoutSetEnabled(row, false);
304  }
305 }
306 
308 {
309  uiLayout *row, *sub;
310  uiLayout *layout = panel->layout;
311 
314 
315  uiLayoutSetContextPointer(panel->layout, "modifier", ptr);
316 
318  bool narrow_panel = (panel->sizex < UI_UNIT_X * 9 && panel->sizex != 0);
319 
320  /* Modifier Icon. */
321  row = uiLayoutRow(layout, false);
322  if (mti->isDisabled && mti->isDisabled(md, 0)) {
323  uiLayoutSetRedAlert(row, true);
324  }
325  uiItemL(row, "", RNA_struct_ui_icon(ptr->type));
326 
327  /* Modifier name. */
328  row = uiLayoutRow(layout, true);
329  if (!narrow_panel) {
330  uiItemR(row, ptr, "name", 0, "", ICON_NONE);
331  }
332  else {
334  }
335 
336  /* Display mode buttons. */
338  sub = uiLayoutRow(row, true);
339  uiItemR(sub, ptr, "show_in_editmode", 0, "", ICON_NONE);
340  }
341  uiItemR(row, ptr, "show_viewport", 0, "", ICON_NONE);
342  uiItemR(row, ptr, "show_render", 0, "", ICON_NONE);
343 
344  /* Extra operators. */
345  // row = uiLayoutRow(layout, true);
346  uiItemMenuF(row, "", ICON_DOWNARROW_HLT, gpencil_modifier_ops_extra_draw, md);
347 
348  /* Remove button. */
349  sub = uiLayoutRow(row, true);
351  uiItemO(sub, "", ICON_X, "OBJECT_OT_gpencil_modifier_remove");
352 
353  /* Extra padding. */
354  uiItemS(layout);
355 }
356 
359 /* -------------------------------------------------------------------- */
368  PanelDrawFn draw)
369 {
370  PanelType *panel_type = MEM_callocN(sizeof(PanelType), __func__);
371 
373  BLI_strncpy(panel_type->label, "", BKE_ST_MAXNAME);
374  BLI_strncpy(panel_type->context, "modifier", BKE_ST_MAXNAME);
376 
378  panel_type->draw = draw;
379  panel_type->poll = gpencil_modifier_ui_poll;
380 
381  /* Give the panel the special flag that says it was built here and corresponds to a
382  * modifier rather than a #PanelType. */
384  panel_type->reorder = gpencil_modifier_reorder;
387 
388  BLI_addtail(&region_type->paneltypes, panel_type);
389 
390  return panel_type;
391 }
392 
400  const char *name,
401  const char *label,
402  PanelDrawFn draw_header,
403  PanelDrawFn draw,
404  PanelType *parent)
405 {
406  PanelType *panel_type = MEM_callocN(sizeof(PanelType), __func__);
407 
408  BLI_snprintf(panel_type->idname, BKE_ST_MAXNAME, "%s_%s", parent->idname, name);
409  BLI_strncpy(panel_type->label, label, BKE_ST_MAXNAME);
410  BLI_strncpy(panel_type->context, "modifier", BKE_ST_MAXNAME);
412 
413  panel_type->draw_header = draw_header;
414  panel_type->draw = draw;
415  panel_type->poll = gpencil_modifier_ui_poll;
417 
418  BLI_assert(parent != NULL);
419  BLI_strncpy(panel_type->parent_id, parent->idname, BKE_ST_MAXNAME);
420  panel_type->parent = parent;
421  BLI_addtail(&parent->children, BLI_genericNodeN(panel_type));
422  BLI_addtail(&region_type->paneltypes, panel_type);
423 
424  return panel_type;
425 }
426 
void BKE_gpencil_modifierType_panel_id(GpencilModifierType type, char *r_idname)
@ eGpencilModifierTypeFlag_SupportsEditmode
@ eGpencilModifierTypeFlag_NoApply
const GpencilModifierTypeInfo * BKE_gpencil_modifier_get_info(GpencilModifierType type)
General operations, lookup, etc. for materials.
struct Material * BKE_object_material_get(struct Object *ob, short act)
Definition: material.c:697
#define BKE_ST_MAXNAME
Definition: BKE_screen.h:68
@ PANEL_TYPE_DRAW_BOX
Definition: BKE_screen.h:305
@ PANEL_TYPE_INSTANCED
Definition: BKE_screen.h:303
@ PANEL_TYPE_DEFAULT_CLOSED
Definition: BKE_screen.h:297
@ PANEL_TYPE_HEADER_EXPAND
Definition: BKE_screen.h:300
#define BLI_assert(a)
Definition: BLI_assert.h:58
struct LinkData * BLI_genericNodeN(void *data)
Definition: listbase.c:923
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define UNUSED(x)
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
#define IFACE_(msgid)
#define BLT_I18NCONTEXT_DEFAULT_BPYRNA
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
Object is a sort of wrapper for general info.
@ OB_GPENCIL
struct Object * ED_object_active_context(const struct bContext *C)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
PointerRNA * gpencil_modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
static void gpencil_modifier_ops_extra_draw(bContext *C, uiLayout *layout, void *md_v)
void gpencil_modifier_masking_panel_draw(Panel *panel, bool use_material, bool use_vertex)
void gpencil_modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
static void set_gpencil_modifier_expand_flag(const bContext *UNUSED(C), Panel *panel, short expand_flag)
static void gpencil_modifier_panel_header(const bContext *UNUSED(C), Panel *panel)
PanelType * gpencil_modifier_subpanel_register(ARegionType *region_type, const char *name, const char *label, PanelDrawFn draw_header, PanelDrawFn draw, PanelType *parent)
PanelType * gpencil_modifier_panel_register(ARegionType *region_type, GpencilModifierType type, PanelDrawFn draw)
void gpencil_modifier_curve_header_draw(const bContext *UNUSED(C), Panel *panel)
static bool gpencil_modifier_ui_poll(const bContext *C, PanelType *UNUSED(pt))
static void gpencil_modifier_reorder(bContext *C, Panel *panel, int new_index)
static short get_gpencil_modifier_expand_flag(const bContext *UNUSED(C), Panel *panel)
#define ERROR_LIBDATA_MESSAGE
void gpencil_modifier_curve_panel_draw(const bContext *UNUSED(C), Panel *panel)
StructRNA RNA_Object
StructRNA RNA_GpencilModifier
#define C
Definition: RandGen.cpp:39
void uiLayoutSetActive(uiLayout *layout, bool active)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
@ UI_EMBOSS_NONE
Definition: UI_interface.h:108
void uiTemplateCurveMapping(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int type, bool levels, bool brush, bool neg_slope, bool tone)
void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext)
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, struct IDProperty *properties, int context, int flag, struct PointerRNA *r_opptr)
void UI_block_lock_clear(uiBlock *block)
Definition: interface.c:2219
void uiItemL(uiLayout *layout, const char *name, int icon)
void uiLayoutSetRedAlert(uiLayout *layout, bool redalert)
struct PointerRNA * UI_panel_custom_data_get(const struct Panel *panel)
void uiLayoutSetAlignment(uiLayout *layout, char alignment)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
@ UI_LAYOUT_ALIGN_RIGHT
void uiLayoutSetUnitsX(uiLayout *layout, float unit)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiLayoutSetEmboss(uiLayout *layout, eUIEmbossType emboss)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
void uiLayoutSetContextPointer(uiLayout *layout, const char *name, struct PointerRNA *ptr)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
void uiItemMenuF(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg)
#define UI_UNIT_X
void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, struct PointerRNA *searchptr, const char *searchpropname, const char *name, int icon)
void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr)
Definition: interface.c:2211
@ WM_OP_INVOKE_DEFAULT
Definition: WM_types.h:197
const char * label
void(* PanelDrawFn)(const bContext *, struct Panel *)
Definition: fmodifier_ui.c:61
uint col
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
Definition: rna_access.c:844
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:6550
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6562
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6319
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
int RNA_struct_ui_icon(const StructRNA *type)
Definition: rna_access.c:738
int RNA_string_length(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6539
bool RNA_pointer_is_null(const PointerRNA *ptr)
Definition: rna_access.c:174
ListBase paneltypes
Definition: BKE_screen.h:216
struct GpencilModifierData * next
struct GpencilModifierData * prev
GpencilModifierTypeFlag flags
bool(* isDisabled)(struct GpencilModifierData *md, int userRenderParams)
ListBase greasepencil_modifiers
short(* get_list_data_expand_flag)(const struct bContext *C, struct Panel *pa)
Definition: BKE_screen.h:278
void(* draw)(const struct bContext *C, struct Panel *panel)
Definition: BKE_screen.h:266
bool(* poll)(const struct bContext *C, struct PanelType *pt)
Definition: BKE_screen.h:260
void(* draw_header)(const struct bContext *C, struct Panel *panel)
Definition: BKE_screen.h:262
char idname[BKE_ST_MAXNAME]
Definition: BKE_screen.h:241
void(* set_list_data_expand_flag)(const struct bContext *C, struct Panel *pa, short expand_flag)
Definition: BKE_screen.h:285
char context[BKE_ST_MAXNAME]
Definition: BKE_screen.h:245
void(* reorder)(struct bContext *C, struct Panel *pa, int new_index)
Definition: BKE_screen.h:271
char translation_context[BKE_ST_MAXNAME]
Definition: BKE_screen.h:244
ListBase children
Definition: BKE_screen.h:289
struct PanelType * parent
Definition: BKE_screen.h:288
char label[BKE_ST_MAXNAME]
Definition: BKE_screen.h:242
char parent_id[BKE_ST_MAXNAME]
Definition: BKE_screen.h:248
struct uiLayout * layout
struct StructRNA * type
Definition: RNA_types.h:51
void * data
Definition: RNA_types.h:52
struct ID * owner_id
Definition: RNA_types.h:50
int WM_operator_name_call_ptr(bContext *C, wmOperatorType *ot, short context, PointerRNA *properties)
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
Definition: wm_operators.c:584
void WM_operator_properties_free(PointerRNA *ptr)
Definition: wm_operators.c:711