Fix issue #82 "visible artifacts while dragging selection".

Also improved the redrawing of the moved selection (redrawing
only the selection bounds instead of the whole sprite).
+ Added TransformHandles::invalidateHandles;
+ Added Widget::invalidateRect(const gfx::Rect&);
This commit is contained in:
David Capello 2012-03-19 20:48:08 -03:00
parent be82a49f86
commit 7771d3fb17
6 changed files with 70 additions and 5 deletions

View File

@ -1154,6 +1154,15 @@ void Widget::invalidate()
}
}
void Widget::invalidateRect(const gfx::Rect& rect)
{
if (isVisible()) {
JRect tmp = jrect_new(rect.x, rect.y, rect.x+rect.w, rect.y+rect.h);
invalidateRect(tmp);
jrect_free(tmp);
}
}
void Widget::invalidateRect(const JRect rect)
{
if (isVisible()) {

View File

@ -277,6 +277,7 @@ public:
void setDoubleBuffered(bool doubleBuffered);
void invalidate();
void invalidateRect(const gfx::Rect& rect);
void invalidateRect(const JRect rect);
void invalidateRegion(const JRegion region);

View File

@ -247,6 +247,11 @@ bool MovingPixelsState::onMouseMove(Editor* editor, Message* msg)
if (editor->getCustomizationDelegate()->isMaintainAspectRatioKeyPressed())
moveModifier |= PixelsMovement::MaintainAspectRatioMovement;
// Invalidate handles area.
Decorator* decorator = static_cast<Decorator*>(editor->getDecorator());
TransformHandles* transfHandles = decorator->getTransformHandles(editor);
transfHandles->invalidateHandles(editor, m_pixelsMovement->getTransformation());
// Drag the image to that position
gfx::Rect bounds = m_pixelsMovement->moveImage(x, y, moveModifier);
@ -254,10 +259,10 @@ bool MovingPixelsState::onMouseMove(Editor* editor, Message* msg)
if (!bounds.isEmpty()) {
// Redraw the extra cel in the new position
jmouse_hide();
editors_draw_sprite_tiled(editor->getSprite(),
bounds.x, bounds.y,
bounds.x+bounds.w-1,
bounds.y+bounds.h-1);
editors_draw_sprite(editor->getSprite(),
bounds.x, bounds.y,
bounds.x+bounds.w-1,
bounds.y+bounds.h-1);
jmouse_show();
}
editor->updateStatusBar();

View File

@ -172,6 +172,9 @@ void PixelsMovement::maskImage(const Image* image, int x, int y)
gfx::Rect PixelsMovement::moveImage(int x, int y, MoveModifier moveModifier)
{
gfx::Transformation::Corners oldCorners;
m_currentData.transformBox(oldCorners);
DocumentWriter documentWriter(m_documentReader);
Image* image = documentWriter->getExtraCelImage();
Cel* cel = documentWriter->getExtraCel();
@ -379,7 +382,18 @@ gfx::Rect PixelsMovement::moveImage(int x, int y, MoveModifier moveModifier)
documentWriter->setTransformation(m_currentData);
return gfx::Rect(0, 0, m_sprite->getWidth(), m_sprite->getHeight());
// Get the new transformed corners
gfx::Transformation::Corners newCorners;
m_currentData.transformBox(newCorners);
// Create a union of all corners, and that will be the bounds to
// redraw of the sprite.
gfx::Rect fullBounds;
for (int i=0; i<gfx::Transformation::Corners::NUM_OF_CORNERS; ++i) {
fullBounds = fullBounds.createUnion(gfx::Rect(oldCorners[i].x, oldCorners[i].y, 1, 1));
fullBounds = fullBounds.createUnion(gfx::Rect(newCorners[i].x, newCorners[i].y, 1, 1));
}
return fullBounds;
}
Image* PixelsMovement::getDraggedImageCopy(gfx::Point& origin)

View File

@ -153,6 +153,41 @@ void TransformHandles::drawHandles(Editor* editor, const gfx::Transformation& tr
}
}
void TransformHandles::invalidateHandles(Editor* editor, const gfx::Transformation& transform)
{
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
fixed angle = ftofix(128.0 * transform.angle() / PI);
gfx::Transformation::Corners corners;
transform.transformBox(corners);
std::vector<int> x(corners.size());
std::vector<int> y(corners.size());
for (size_t c=0; c<corners.size(); ++c)
editor->editorToScreen(corners[c].x, corners[c].y, &x[c], &y[c]);
// Invalidate each corner handle.
for (size_t c=0; c<HANDLES; ++c) {
BITMAP* gfx = theme->get_part(PART_TRANSFORMATION_HANDLE);
int u = (x[handles_info[c].i1]+x[handles_info[c].i2])/2;
int v = (y[handles_info[c].i1]+y[handles_info[c].i2])/2;
adjustHandle(u, v, gfx->w, gfx->h, angle + handles_info[c].angle);
editor->invalidateRect(gfx::Rect(u, v, gfx->w, gfx->h));
}
// Invalidate area where the pivot is.
if (angle != 0) {
gfx::Rect pivotBounds = getPivotHandleBounds(editor, transform, corners);
BITMAP* gfx = theme->get_part(PART_PIVOT_HANDLE);
editor->invalidateRect(gfx::Rect(pivotBounds.x,
pivotBounds.y,
gfx->w, gfx->h));
}
}
gfx::Rect TransformHandles::getPivotHandleBounds(Editor* editor,
const gfx::Transformation& transform,
const gfx::Transformation::Corners& corners)

View File

@ -41,6 +41,7 @@ public:
HandleType getHandleAtPoint(Editor* editor, const gfx::Point& pt, const gfx::Transformation& transform);
void drawHandles(Editor* editor, const gfx::Transformation& transform);
void invalidateHandles(Editor* editor, const gfx::Transformation& transform);
private:
gfx::Rect getPivotHandleBounds(Editor* editor,