GPencil: "Add Blank Frame" operator (D+B)
This operator adds a new frame with nothing in it on the current frame. If there is already a frame there, all existing frames are shifted one frame later. Quite often when animating, you may want a quick way to get a blank frame, ready to start drawing something new. Or maybe you just need a quick way to add a "placeholder" frame so that a suddenly-appearing element does not show up before its time.
This commit is contained in:
parent
86b6006ef8
commit
259447300f
@ -115,6 +115,12 @@ class GreasePencilDrawingToolsPanel:
|
||||
row.operator("gpencil.draw", icon='LINE_DATA', text="Line").mode = 'DRAW_STRAIGHT'
|
||||
row.operator("gpencil.draw", icon='MESH_DATA', text="Poly").mode = 'DRAW_POLY'
|
||||
|
||||
col.separator()
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.operator("gpencil.blank_frame_add", icon='NEW')
|
||||
sub.operator("gpencil.active_frames_delete_all", icon='X', text="Delete Frame(s)")
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.prop(context.tool_settings, "use_gpencil_additive_drawing", text="Additive Drawing")
|
||||
sub.prop(context.tool_settings, "use_gpencil_continuous_drawing", text="Continuous Drawing")
|
||||
|
@ -682,6 +682,80 @@ void GPENCIL_OT_move_to_layer(wmOperatorType *ot)
|
||||
RNA_def_enum_funcs(ot->prop, ED_gpencil_layers_with_new_enum_itemf);
|
||||
}
|
||||
|
||||
/* ********************* Add Blank Frame *************************** */
|
||||
|
||||
/* Basically the same as the drawing op */
|
||||
static int gp_blank_frame_add_poll(bContext *C)
|
||||
{
|
||||
if (ED_operator_regionactive(C)) {
|
||||
/* check if current context can support GPencil data */
|
||||
if (ED_gpencil_data_get_pointers(C, NULL) != NULL) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
CTX_wm_operator_poll_msg_set(C, "Failed to find Grease Pencil data to draw into");
|
||||
}
|
||||
}
|
||||
else {
|
||||
CTX_wm_operator_poll_msg_set(C, "Active region not set");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gp_blank_frame_add_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
bGPdata *gpd = ED_gpencil_data_get_active(C);
|
||||
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
|
||||
|
||||
/* Initialise datablock and an active layer if nothing exists yet */
|
||||
if (ELEM(NULL, gpd, gpl)) {
|
||||
/* let's just be lazy, and call the "Add New Layer" operator, which sets everything up as required */
|
||||
WM_operator_name_call(C, "GPENCIL_OT_layer_add", WM_OP_EXEC_DEFAULT, NULL);
|
||||
}
|
||||
|
||||
/* Go through each layer, adding a frame after the active one
|
||||
* and/or shunting all the others out of the way
|
||||
*/
|
||||
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
|
||||
{
|
||||
/* 1) Check for an existing frame on the current frame */
|
||||
bGPDframe *gpf = BKE_gpencil_layer_find_frame(gpl, CFRA);
|
||||
if (gpf) {
|
||||
/* Shunt all frames after (and including) the existing one later by 1-frame */
|
||||
for (; gpf; gpf = gpf->next) {
|
||||
gpf->framenum += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2) Now add a new frame, with nothing in it */
|
||||
gpl->actframe = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_NEW);
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
/* notifiers */
|
||||
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void GPENCIL_OT_blank_frame_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add Blank Frame";
|
||||
ot->idname = "GPENCIL_OT_blank_frame_add";
|
||||
ot->description = "Add a new frame with nothing in it on the current frame. "
|
||||
"If there is already a frame, all existing frames are shifted one frame later";
|
||||
|
||||
/* callbacks */
|
||||
ot->exec = gp_blank_frame_add_exec;
|
||||
ot->poll = gp_add_poll;
|
||||
|
||||
/* properties */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
/* ******************* Delete Active Frame ************************ */
|
||||
|
||||
static int gp_actframe_delete_poll(bContext *C)
|
||||
|
@ -287,6 +287,8 @@ void GPENCIL_OT_unlock_all(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_layer_isolate(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_layer_merge(struct wmOperatorType *ot);
|
||||
|
||||
void GPENCIL_OT_blank_frame_add(struct wmOperatorType *ot);
|
||||
|
||||
void GPENCIL_OT_active_frame_delete(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_active_frames_delete_all(struct wmOperatorType *ot);
|
||||
|
||||
|
@ -102,6 +102,10 @@ static void ed_keymap_gpencil_general(wmKeyConfig *keyconf)
|
||||
WM_keymap_add_menu_pie(keymap, "GPENCIL_PIE_tool_palette", QKEY, KM_PRESS, 0, DKEY);
|
||||
WM_keymap_add_menu_pie(keymap, "GPENCIL_PIE_settings_palette", WKEY, KM_PRESS, 0, DKEY);
|
||||
|
||||
/* Add Blank Frame */
|
||||
/* XXX: BKEY or NKEY? BKEY is easier to reach from DKEY, so we'll use that for now */
|
||||
WM_keymap_add_item(keymap, "GPENCIL_OT_blank_frame_add", BKEY, KM_PRESS, 0, DKEY);
|
||||
|
||||
/* Delete Active Frame - For easier video tutorials/review sessions */
|
||||
/* NOTE: This works even when not in EditMode */
|
||||
WM_keymap_add_item(keymap, "GPENCIL_OT_active_frames_delete_all", XKEY, KM_PRESS, 0, DKEY);
|
||||
@ -401,6 +405,8 @@ void ED_operatortypes_gpencil(void)
|
||||
WM_operatortype_append(GPENCIL_OT_layer_isolate);
|
||||
WM_operatortype_append(GPENCIL_OT_layer_merge);
|
||||
|
||||
WM_operatortype_append(GPENCIL_OT_blank_frame_add);
|
||||
|
||||
WM_operatortype_append(GPENCIL_OT_active_frame_delete);
|
||||
WM_operatortype_append(GPENCIL_OT_active_frames_delete_all);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user