GPencil: Add material selector to context menus

Now it's possible to select the material in context menu and new menu to select material.

The patch and workflow  has been tested in greasepencil-object branch.

* New Material selector in Draw mode Context menu:

{F8499259}

* Pressing `U`key in Draw mode display material menu.

{F8503224}

Reviewed By: mendio, pepeland

Differential Revision: https://developer.blender.org/D7554
This commit is contained in:
Antonio Vazquez 2020-04-30 16:12:34 +02:00 committed by Antonio Vazquez
parent dc0a564c06
commit 6a7e9f2b76
8 changed files with 138 additions and 9 deletions

View File

@ -3226,6 +3226,8 @@ def km_grease_pencil_stroke_paint_mode(params):
{"properties": [("unselected", True)]}),
# Active layer
op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}),
# Active material
op_menu("GPENCIL_MT_material_active", {"type": 'U', "value": 'PRESS'}),
# Keyframe menu
op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}),
# Draw context menu

View File

@ -2374,7 +2374,7 @@ def km_grease_pencil_stroke_paint_mode(params):
op_tool_cycle("builtin.cutter", {"type": 'K', "value": 'PRESS'}),
op_tool_cycle("builtin.cursor", {"type": 'C', "value": 'PRESS'}),
# Active layer
op_menu("GPENCIL_MT_layer_active", {"type": 'M', "value": 'PRESS'}),
op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}),
# Keyframe menu
op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}),
])

View File

@ -361,6 +361,35 @@ class GPENCIL_MT_layer_active(Menu):
layout.operator("gpencil.layer_add", text="New Layer", icon='ADD')
class GPENCIL_MT_material_active(Menu):
bl_label = "Change Active Material"
@classmethod
def poll(cls, context):
ob = context.active_object
tool_settings = context.scene.tool_settings
mode = tool_settings.gpencil_paint.color_mode
if mode != 'MATERIAL':
return False
if ob is None or len(ob.material_slots) == 0:
return False
return True
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
ob = context.active_object
mat_active = ob.active_material
for slot in ob.material_slots:
mat = slot.material
if mat:
icon = mat.id_data.preview.icon_id
layout.operator("gpencil.material_set", text=mat.name, icon_value=icon).slot = mat.name
class GPENCIL_MT_gpencil_draw_delete(Menu):
bl_label = "Delete"
@ -632,8 +661,8 @@ class GreasePencilMaterialsPanel:
if ob.data.use_stroke_edit_mode:
row = layout.row(align=True)
row.operator("gpencil.stroke_change_color", text="Assign")
row.operator("gpencil.select_material", text="Select").deselect = False
row.operator("gpencil.select_material", text="Deselect").deselect = True
row.operator("gpencil.material_select", text="Select").deselect = False
row.operator("gpencil.material_select", text="Deselect").deselect = True
# stroke color
ma = None
if is_view3d and brush is not None:
@ -931,6 +960,7 @@ classes = (
GPENCIL_MT_cleanup,
GPENCIL_MT_move_to_layer,
GPENCIL_MT_layer_active,
GPENCIL_MT_material_active,
GPENCIL_MT_gpencil_draw_delete,
GPENCIL_MT_layer_mask_menu,

View File

@ -7060,6 +7060,18 @@ def draw_gpencil_layer_active(context, layout):
row.operator("gpencil.layer_remove", text="", icon='X')
def draw_gpencil_material_active(context, layout):
ob = context.active_object
if ob and len(ob.material_slots) > 0 and ob.active_material_index >= 0:
ma = ob.material_slots[ob.active_material_index].material
if ma:
layout.label(text="Active Material")
row = layout.row(align=True)
row.operator_context = 'EXEC_REGION_WIN'
row.operator_menu_enum("gpencil.material_set", "slot", text="", icon='MATERIAL')
row.prop(ma, "name", text="")
class VIEW3D_PT_gpencil_sculpt_context_menu(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'WINDOW'
@ -7133,6 +7145,9 @@ class VIEW3D_PT_gpencil_draw_context_menu(Panel):
# Layers
draw_gpencil_layer_active(context, layout)
# Material
if not is_vertex:
draw_gpencil_material_active(context, layout)
class VIEW3D_PT_gpencil_vertex_context_menu(Panel):

View File

@ -3193,7 +3193,7 @@ void GPENCIL_OT_material_unlock_all(wmOperatorType *ot)
/* ***************** Select all strokes using color ************************ */
static int gpencil_select_material_exec(bContext *C, wmOperator *op)
static int gpencil_material_select_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
Object *ob = CTX_data_active_object(C);
@ -3263,15 +3263,15 @@ static int gpencil_select_material_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
void GPENCIL_OT_select_material(wmOperatorType *ot)
void GPENCIL_OT_material_select(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select Material";
ot->idname = "GPENCIL_OT_select_material";
ot->idname = "GPENCIL_OT_material_select";
ot->description = "Select/Deselect all Grease Pencil strokes using current material";
/* callbacks */
ot->exec = gpencil_select_material_exec;
ot->exec = gpencil_material_select_exec;
ot->poll = gpencil_active_material_poll;
/* flags */
@ -3282,6 +3282,48 @@ void GPENCIL_OT_select_material(wmOperatorType *ot)
RNA_def_property_flag(ot->prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
/* ***************** Set active material ************************* */
static int gpencil_material_set_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
int slot = RNA_enum_get(op->ptr, "slot");
/* Try to get material */
if ((slot < 1) || (slot > ob->totcol)) {
BKE_reportf(
op->reports, RPT_ERROR, "Cannot change to non-existent material (index = %d)", slot);
return OPERATOR_CANCELLED;
}
/* Set active material. */
ob->actcol = slot;
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
}
void GPENCIL_OT_material_set(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Set Material";
ot->idname = "GPENCIL_OT_material_set";
ot->description = "Set active material";
/* callbacks */
ot->exec = gpencil_material_set_exec;
ot->poll = gpencil_active_material_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* Material to use (dynamic enum) */
ot->prop = RNA_def_enum(ot->srna, "slot", DummyRNA_DEFAULT_items, 0, "Material Slot", "");
RNA_def_enum_funcs(ot->prop, ED_gpencil_material_enum_itemf);
}
/* ***************** Set selected stroke material the active material ************************ */
static int gpencil_set_active_material_exec(bContext *C, wmOperator *op)

View File

@ -345,6 +345,10 @@ const struct EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(struct bCon
struct PointerRNA *ptr,
struct PropertyRNA *prop,
bool *r_free);
const struct EnumPropertyItem *ED_gpencil_material_enum_itemf(struct bContext *C,
struct PointerRNA *ptr,
struct PropertyRNA *prop,
bool *r_free);
/* ***************************************************** */
/* Operator Defines */
@ -550,7 +554,8 @@ void GPENCIL_OT_material_reveal(struct wmOperatorType *ot);
void GPENCIL_OT_material_lock_all(struct wmOperatorType *ot);
void GPENCIL_OT_material_unlock_all(struct wmOperatorType *ot);
void GPENCIL_OT_material_lock_unused(struct wmOperatorType *ot);
void GPENCIL_OT_select_material(struct wmOperatorType *ot);
void GPENCIL_OT_material_select(struct wmOperatorType *ot);
void GPENCIL_OT_material_set(struct wmOperatorType *ot);
void GPENCIL_OT_set_active_material(struct wmOperatorType *ot);
/* convert old 2.7 files to 2.8 */

View File

@ -653,7 +653,8 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_material_reveal);
WM_operatortype_append(GPENCIL_OT_material_lock_all);
WM_operatortype_append(GPENCIL_OT_material_unlock_all);
WM_operatortype_append(GPENCIL_OT_select_material);
WM_operatortype_append(GPENCIL_OT_material_select);
WM_operatortype_append(GPENCIL_OT_material_set);
/* Editing (Time) --------------- */

View File

@ -481,6 +481,40 @@ const EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(bContext *C,
return item;
}
/* Just existing Materials */
const EnumPropertyItem *ED_gpencil_material_enum_itemf(bContext *C,
PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop),
bool *r_free)
{
Object *ob = CTX_data_active_object(C);
EnumPropertyItem *item = NULL, item_tmp = {0};
int totitem = 0;
int i = 0;
if (ELEM(NULL, C, ob)) {
return DummyRNA_DEFAULT_items;
}
/* Existing materials */
for (i = 1; i <= ob->totcol; i++) {
Material *ma = BKE_object_material_get(ob, i);
if (ma) {
item_tmp.identifier = ma->id.name + 2;
item_tmp.name = ma->id.name + 2;
item_tmp.value = i;
item_tmp.icon = ma->preview->icon_id;
RNA_enum_item_add(&item, &totitem, &item_tmp);
}
}
RNA_enum_item_end(&item, &totitem);
*r_free = true;
return item;
}
/* ******************************************************** */
/* Brush Tool Core */