Skip to content

Commit c490158

Browse files
committed
[[ Bug 17247 ]] Make sure selection handles are invalidated when object rect changes.
1 parent 1a9069c commit c490158

File tree

6 files changed

+48
-17
lines changed

6 files changed

+48
-17
lines changed

docs/notes/bugfix-17247.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Remove selection artefacts when handles are drawn outside of parent group rect

engine/src/card.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3030,6 +3030,20 @@ void MCCard::drawselectedchildren(MCDC *dc)
30303030
while (tptr != objptrs);
30313031
}
30323032

3033+
void MCCard::dirtyselection(const MCRectangle &p_rect)
3034+
{
3035+
// redraw marquee rect
3036+
// selrect with 0 width or height will still draw a 1px line, so increase rect size to account for this.
3037+
layer_dirtyrect(MCU_reduce_rect(p_rect, -1));
3038+
3039+
// redraw selection handles
3040+
MCRectangle t_handles[8];
3041+
MCControl::sizerects(p_rect, t_handles);
3042+
3043+
for (uint32_t i = 0; i < 8; i++)
3044+
layer_dirtyrect(t_handles[i]);
3045+
}
3046+
30333047
bool MCCard::updatechildselectedrect(MCRectangle& x_rect)
30343048
{
30353049
bool t_updated;

engine/src/card.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ class MCCard : public MCObject
215215
// IM-2013-09-13: [[ RefactorGraphics ]] render the card selection rect
216216
void drawselectionrect(MCContext *);
217217
void drawselectedchildren(MCDC *dc);
218+
219+
// IM-2016-09-26: [[ Bug 17247 ]] request redraw of the area occupied by
220+
// selection marquee + handles
221+
void dirtyselection(const MCRectangle &p_rect);
222+
218223
bool updatechildselectedrect(MCRectangle& x_rect);
219224

220225
Exec_stat openbackgrounds(bool p_is_preopen, MCCard *p_other);

engine/src/control.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,8 @@ void MCControl::select()
433433

434434
// MW-2011-08-18: [[ Layers ]] Invalidate the whole object.
435435
layer_redrawall();
436+
437+
getcard()->dirtyselection(rect);
436438
}
437439

438440
void MCControl::deselect()
@@ -446,6 +448,8 @@ void MCControl::deselect()
446448
// MW-2011-08-18: [[ Layers ]] Invalidate the whole object.
447449
layer_redrawall();
448450

451+
getcard()->dirtyselection(rect);
452+
449453
state &= ~(CS_SELECTED | CS_MOVE | CS_SIZE | CS_CREATE);
450454
}
451455
}
@@ -790,30 +794,30 @@ void MCControl::redraw(MCDC *dc, const MCRectangle &dirty)
790794
}
791795
}
792796

793-
void MCControl::sizerects(MCRectangle *rects)
797+
void MCControl::sizerects(const MCRectangle &p_object_rect, MCRectangle r_rects[8])
794798
{
795799
int2 x[3];
796800
int2 y[3];
797801

798802
uint2 handlesize = MCsizewidth;
799-
800-
x[0] = rect.x - (handlesize >> 1);
801-
x[1] = rect.x + ((rect.width - handlesize) >> 1);
802-
x[2] = rect.x + rect.width - (handlesize >> 1);
803-
y[0] = rect.y - (handlesize >> 1);
804-
y[1] = rect.y + ((rect.height - handlesize) >> 1);
805-
y[2] = rect.y + rect.height - (handlesize >> 1);
806803

804+
x[0] = p_object_rect.x - (handlesize >> 1);
805+
x[1] = p_object_rect.x + ((p_object_rect.width - handlesize) >> 1);
806+
x[2] = p_object_rect.x + p_object_rect.width - (handlesize >> 1);
807+
y[0] = p_object_rect.y - (handlesize >> 1);
808+
y[1] = p_object_rect.y + ((p_object_rect.height - handlesize) >> 1);
809+
y[2] = p_object_rect.y + p_object_rect.height - (handlesize >> 1);
810+
807811
uint2 i;
808812
uint2 j;
809813
uint2 k = 0;
810814
for (i = 0 ; i < 3 ; i++)
811815
for (j = 0 ; j < 3 ; j++)
812816
if (i != 1 || j != 1)
813817
{
814-
rects[k].width = rects[k].height = handlesize;
815-
rects[k].x = x[j];
816-
rects[k].y = y[i];
818+
r_rects[k].width = r_rects[k].height = handlesize;
819+
r_rects[k].x = x[j];
820+
r_rects[k].y = y[i];
817821
k++;
818822
}
819823
}
@@ -833,7 +837,7 @@ void MCControl::drawselected(MCDC *dc)
833837
drawmarquee(dc, rect);
834838

835839
MCRectangle rects[8];
836-
sizerects(rects);
840+
sizerects(rect, rects);
837841
if (flags & F_LOCK_LOCATION)
838842
dc->setfillstyle(FillStippled, nil, 0, 0);
839843
else
@@ -1173,7 +1177,7 @@ uint2 MCControl::sizehandles(int2 px, int2 py)
11731177
if (!(flags & F_LOCK_LOCATION))
11741178
{
11751179
MCRectangle rects[8];
1176-
sizerects(rects);
1180+
sizerects(rect, rects);
11771181
int2 i;
11781182
for (i = 7 ; i >= 0 ; i--)
11791183
{
@@ -1719,9 +1723,6 @@ MCRectangle MCControl::geteffectiverect(void) const
17191723
MCRectangle t_rect;
17201724
t_rect = MCU_reduce_rect(rect, -gettransient());
17211725

1722-
if (state & CS_SELECTED)
1723-
t_rect = MCU_reduce_rect(t_rect, -MCsizewidth);
1724-
17251726
if (m_bitmap_effects != nil)
17261727
MCBitmapEffectsComputeBounds(m_bitmap_effects, t_rect, t_rect);
17271728

engine/src/mccontrol.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,9 @@ class MCControl : public MCObject
156156

157157
void redraw(MCDC *dc, const MCRectangle &dirty);
158158

159-
void sizerects(MCRectangle *rects);
159+
// IM-2016-09-26: [[ Bug 17247 ]] Return rect of selection handles for the given object rect
160+
static void sizerects(const MCRectangle &p_object_rect, MCRectangle rects[8]);
161+
160162
void drawselected(MCDC *dc);
161163
void drawarrow(MCDC *dc, int2 x, int2 y, uint2 size,
162164
Arrow_direction dir, Boolean border, Boolean hilite);

engine/src/redraw.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,10 @@ void MCControl::layer_setrect(const MCRectangle& p_new_rect, bool p_redraw_all)
358358
return;
359359
}
360360

361+
// IM-2016-09-26: [[ Bug 17247 ]] dirty old selection rect
362+
if (getselected())
363+
getcard()->dirtyselection(rect);
364+
361365
MCRectangle t_old_effectiverect;
362366
t_old_effectiverect = geteffectiverect();
363367

@@ -369,6 +373,10 @@ void MCControl::layer_setrect(const MCRectangle& p_new_rect, bool p_redraw_all)
369373

370374
setrect(p_new_rect);
371375

376+
// IM-2016-09-26: [[ Bug 17247 ]] dirty new selection rect
377+
if (getselected())
378+
getcard()->dirtyselection(rect);
379+
372380
layer_changeeffectiverect(t_old_effectiverect, p_redraw_all, t_is_visible);
373381
}
374382

0 commit comments

Comments
 (0)