Fix T65591: GPencil Arrange Strokes operator does not work in multiframe
This commit is contained in:
parent
f765e0cd21
commit
3ebee7c496
Notes:
blender-bot
2023-02-14 05:37:19 +01:00
Referenced by issue #65591, GPencil "Arrange Strokes" operator does not work in multiframe
|
@ -1276,6 +1276,7 @@ static int gp_stroke_arrange_exec(bContext *C, wmOperator *op)
|
|||
bGPdata *gpd = ED_gpencil_data_get_active(C);
|
||||
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
|
||||
bGPDstroke *gps;
|
||||
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
|
||||
|
||||
/* sanity checks */
|
||||
if (ELEM(NULL, gpd, gpl, gpl->actframe)) {
|
||||
|
@ -1284,90 +1285,99 @@ static int gp_stroke_arrange_exec(bContext *C, wmOperator *op)
|
|||
|
||||
const int direction = RNA_enum_get(op->ptr, "direction");
|
||||
|
||||
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
/* temp listbase to store selected strokes by layer */
|
||||
CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
|
||||
/* temp listbase to store selected strokes */
|
||||
ListBase selected = {NULL};
|
||||
bGPDframe *gpf = gpl->actframe;
|
||||
if (gpl->flag & GP_LAYER_LOCKED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gpf == NULL) {
|
||||
continue;
|
||||
}
|
||||
bool gpf_lock = false;
|
||||
/* verify if any selected stroke is in the extreme of the stack and select to move */
|
||||
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
/* only if selected */
|
||||
if (gps->flag & GP_STROKE_SELECT) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false) {
|
||||
bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
|
||||
bGPDstroke *gps = NULL;
|
||||
|
||||
for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
|
||||
if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
|
||||
if (gpf == NULL) {
|
||||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* some stroke is already at front*/
|
||||
if ((direction == GP_STROKE_MOVE_TOP) || (direction == GP_STROKE_MOVE_UP)) {
|
||||
if (gps == gpf->strokes.last) {
|
||||
gpf_lock = true;
|
||||
continue;
|
||||
bool gpf_lock = false;
|
||||
/* verify if any selected stroke is in the extreme of the stack and select to move */
|
||||
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
/* only if selected */
|
||||
if (gps->flag & GP_STROKE_SELECT) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* some stroke is already at front*/
|
||||
if ((direction == GP_STROKE_MOVE_TOP) || (direction == GP_STROKE_MOVE_UP)) {
|
||||
if (gps == gpf->strokes.last) {
|
||||
gpf_lock = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* some stroke is already at botom */
|
||||
if ((direction == GP_STROKE_MOVE_BOTTOM) || (direction == GP_STROKE_MOVE_DOWN)) {
|
||||
if (gps == gpf->strokes.first) {
|
||||
gpf_lock = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* add to list (if not locked) */
|
||||
if (!gpf_lock) {
|
||||
BLI_addtail(&selected, BLI_genericNodeN(gps));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* some stroke is already at botom */
|
||||
if ((direction == GP_STROKE_MOVE_BOTTOM) || (direction == GP_STROKE_MOVE_DOWN)) {
|
||||
if (gps == gpf->strokes.first) {
|
||||
gpf_lock = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* add to list (if not locked) */
|
||||
/* Now do the movement of the stroke */
|
||||
if (!gpf_lock) {
|
||||
BLI_addtail(&selected, BLI_genericNodeN(gps));
|
||||
switch (direction) {
|
||||
/* Bring to Front */
|
||||
case GP_STROKE_MOVE_TOP:
|
||||
for (LinkData *link = selected.first; link; link = link->next) {
|
||||
gps = link->data;
|
||||
BLI_remlink(&gpf->strokes, gps);
|
||||
BLI_addtail(&gpf->strokes, gps);
|
||||
}
|
||||
break;
|
||||
/* Bring Forward */
|
||||
case GP_STROKE_MOVE_UP:
|
||||
for (LinkData *link = selected.last; link; link = link->prev) {
|
||||
gps = link->data;
|
||||
BLI_listbase_link_move(&gpf->strokes, gps, 1);
|
||||
}
|
||||
break;
|
||||
/* Send Backward */
|
||||
case GP_STROKE_MOVE_DOWN:
|
||||
for (LinkData *link = selected.first; link; link = link->next) {
|
||||
gps = link->data;
|
||||
BLI_listbase_link_move(&gpf->strokes, gps, -1);
|
||||
}
|
||||
break;
|
||||
/* Send to Back */
|
||||
case GP_STROKE_MOVE_BOTTOM:
|
||||
for (LinkData *link = selected.last; link; link = link->prev) {
|
||||
gps = link->data;
|
||||
BLI_remlink(&gpf->strokes, gps);
|
||||
BLI_addhead(&gpf->strokes, gps);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
BLI_freelistN(&selected);
|
||||
}
|
||||
|
||||
/* if not multiedit, exit loop*/
|
||||
if (!is_multiedit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Now do the movement of the stroke */
|
||||
if (!gpf_lock) {
|
||||
switch (direction) {
|
||||
/* Bring to Front */
|
||||
case GP_STROKE_MOVE_TOP:
|
||||
for (LinkData *link = selected.first; link; link = link->next) {
|
||||
gps = link->data;
|
||||
BLI_remlink(&gpf->strokes, gps);
|
||||
BLI_addtail(&gpf->strokes, gps);
|
||||
}
|
||||
break;
|
||||
/* Bring Forward */
|
||||
case GP_STROKE_MOVE_UP:
|
||||
for (LinkData *link = selected.last; link; link = link->prev) {
|
||||
gps = link->data;
|
||||
BLI_listbase_link_move(&gpf->strokes, gps, 1);
|
||||
}
|
||||
break;
|
||||
/* Send Backward */
|
||||
case GP_STROKE_MOVE_DOWN:
|
||||
for (LinkData *link = selected.first; link; link = link->next) {
|
||||
gps = link->data;
|
||||
BLI_listbase_link_move(&gpf->strokes, gps, -1);
|
||||
}
|
||||
break;
|
||||
/* Send to Back */
|
||||
case GP_STROKE_MOVE_BOTTOM:
|
||||
for (LinkData *link = selected.last; link; link = link->prev) {
|
||||
gps = link->data;
|
||||
BLI_remlink(&gpf->strokes, gps);
|
||||
BLI_addhead(&gpf->strokes, gps);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
BLI_freelistN(&selected);
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
/* notifiers */
|
||||
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
|
||||
|
|
Loading…
Reference in New Issue