mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-14 04:19:12 +00:00
Fix a crash selecting a tile or pasting clipboard when we are moving the selection boundaries
This is because the MovingSelectionState freeze the document mask, and we should unfreeze it before we execute any other command.
This commit is contained in:
parent
76681dc416
commit
26fbacc772
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2017-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -17,6 +18,7 @@
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "doc/mask.h"
|
||||
#include "ui/message.h"
|
||||
|
||||
@ -25,14 +27,22 @@ namespace app {
|
||||
using namespace ui;
|
||||
|
||||
MovingSelectionState::MovingSelectionState(Editor* editor, MouseMessage* msg)
|
||||
: m_cursorStart(editor->screenToEditor(msg->position()))
|
||||
: m_editor(editor)
|
||||
, m_cursorStart(editor->screenToEditor(msg->position()))
|
||||
, m_selOrigin(editor->document()->mask()->bounds().origin())
|
||||
{
|
||||
editor->captureMouse();
|
||||
|
||||
// Hook BeforeCommandExecution signal so we know if the user wants
|
||||
// to execute other command, so we can unfreeze the document mask.
|
||||
m_ctxConn = UIContext::instance()->BeforeCommandExecution.connect(
|
||||
&MovingSelectionState::onBeforeCommandExecution, this);
|
||||
}
|
||||
|
||||
MovingSelectionState::~MovingSelectionState()
|
||||
void MovingSelectionState::onBeforeCommandExecution(CommandExecutionEvent& ev)
|
||||
{
|
||||
m_editor->backToPreviousState();
|
||||
m_editor->releaseMouse();
|
||||
}
|
||||
|
||||
void MovingSelectionState::onEnterState(Editor* editor)
|
||||
@ -47,6 +57,8 @@ EditorState::LeaveAction MovingSelectionState::onLeaveState(Editor* editor, Edit
|
||||
Mask* mask = doc->mask();
|
||||
gfx::Point newOrigin = mask->bounds().origin();
|
||||
|
||||
ASSERT(mask->isFrozen());
|
||||
|
||||
// Restore the mask to the original state so we can transform it
|
||||
// with the a undoable transaction.
|
||||
mask->setOrigin(m_selOrigin.x,
|
||||
@ -86,15 +98,21 @@ bool MovingSelectionState::onMouseMove(Editor* editor, MouseMessage* msg)
|
||||
const gfx::Point newMaskOrigin = m_selOrigin + m_delta;
|
||||
const gfx::Point oldMaskOrigin = editor->document()->mask()->bounds().origin();
|
||||
|
||||
ASSERT(editor->document()->mask()->isFrozen());
|
||||
|
||||
if (oldMaskOrigin != newMaskOrigin) {
|
||||
editor->document()->mask()->setOrigin(newMaskOrigin.x,
|
||||
newMaskOrigin.y);
|
||||
|
||||
MaskBoundaries* boundaries =
|
||||
const_cast<MaskBoundaries*>(editor->document()->getMaskBoundaries());
|
||||
const gfx::Point boundariesDelta = newMaskOrigin - oldMaskOrigin;
|
||||
boundaries->offset(boundariesDelta.x,
|
||||
boundariesDelta.y);
|
||||
if (MaskBoundaries* boundaries =
|
||||
const_cast<MaskBoundaries*>(editor->document()->getMaskBoundaries())) {
|
||||
const gfx::Point boundariesDelta = newMaskOrigin - oldMaskOrigin;
|
||||
boundaries->offset(boundariesDelta.x,
|
||||
boundariesDelta.y);
|
||||
}
|
||||
else {
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
editor->invalidate();
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2017 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -8,13 +9,14 @@
|
||||
#define APP_UI_EDITOR_MOVING_SELECTION_STATE_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/context.h"
|
||||
#include "app/ui/editor/standby_state.h"
|
||||
#include "obs/connection.h"
|
||||
|
||||
namespace app {
|
||||
class MovingSelectionState : public StandbyState {
|
||||
public:
|
||||
MovingSelectionState(Editor* editor, ui::MouseMessage* msg);
|
||||
virtual ~MovingSelectionState();
|
||||
|
||||
// EditorState
|
||||
virtual void onEnterState(Editor* editor) override;
|
||||
@ -27,9 +29,14 @@ namespace app {
|
||||
virtual bool requireBrushPreview() override { return false; }
|
||||
|
||||
private:
|
||||
// ContextObserver
|
||||
void onBeforeCommandExecution(CommandExecutionEvent& ev);
|
||||
|
||||
Editor* m_editor;
|
||||
gfx::Point m_cursorStart;
|
||||
gfx::Point m_selOrigin;
|
||||
gfx::Point m_delta;
|
||||
obs::scoped_connection m_ctxConn;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2001-2018 David Capello
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -113,6 +114,8 @@ bool Mask::isRectangular() const
|
||||
|
||||
void Mask::copyFrom(const Mask* sourceMask)
|
||||
{
|
||||
ASSERT(m_freeze_count == 0);
|
||||
|
||||
clear();
|
||||
setName(sourceMask->name().c_str());
|
||||
|
||||
@ -120,8 +123,10 @@ void Mask::copyFrom(const Mask* sourceMask)
|
||||
// Add all the area of "mask"
|
||||
add(sourceMask->bounds());
|
||||
|
||||
// And copy the "mask" bitmap
|
||||
copy_image(m_bitmap.get(), sourceMask->m_bitmap.get());
|
||||
// And copy the "mask" bitmap (m_bitmap can be nullptr if this is
|
||||
// frozen, so add() doesn't created the bitmap)
|
||||
if (m_bitmap)
|
||||
copy_image(m_bitmap.get(), sourceMask->m_bitmap.get());
|
||||
}
|
||||
}
|
||||
|
||||
@ -193,11 +198,15 @@ void Mask::add(const gfx::Rect& bounds)
|
||||
if (m_freeze_count == 0)
|
||||
reserve(bounds);
|
||||
|
||||
// m_bitmap can be nullptr if we have m_freeze_count > 0
|
||||
if (!m_bitmap)
|
||||
return;
|
||||
|
||||
fill_rect(m_bitmap.get(),
|
||||
bounds.x-m_bounds.x,
|
||||
bounds.y-m_bounds.y,
|
||||
bounds.x-m_bounds.x+bounds.w-1,
|
||||
bounds.y-m_bounds.y+bounds.h-1, 1);
|
||||
bounds.x-m_bounds.x,
|
||||
bounds.y-m_bounds.y,
|
||||
bounds.x-m_bounds.x+bounds.w-1,
|
||||
bounds.y-m_bounds.y+bounds.h-1, 1);
|
||||
}
|
||||
|
||||
void Mask::subtract(const gfx::Rect& bounds)
|
||||
|
Loading…
x
Reference in New Issue
Block a user