Creating a brush with right-click clear the selected region with bg color (#154)

This commit is contained in:
David Capello 2015-04-27 13:03:02 -03:00
parent 51b6def023
commit 8f500178fc
6 changed files with 163 additions and 5 deletions

View File

@ -71,6 +71,7 @@ add_library(app-lib
cmd/clear_cel.cpp
cmd/clear_image.cpp
cmd/clear_mask.cpp
cmd/clear_rect.cpp
cmd/configure_background.cpp
cmd/copy_cel.cpp
cmd/copy_frame.cpp

View File

@ -0,0 +1,87 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/cmd/clear_rect.h"
#include "app/document.h"
#include "doc/cel.h"
#include "doc/image.h"
#include "doc/layer.h"
#include "doc/primitives.h"
namespace app {
namespace cmd {
using namespace doc;
ClearRect::ClearRect(Cel* cel, const gfx::Rect& bounds)
{
app::Document* doc = static_cast<app::Document*>(cel->document());
Image* image = (cel ? cel->image(): NULL);
if (!image)
return;
m_offsetX = bounds.x - cel->x();
m_offsetY = bounds.y - cel->y();
gfx::Rect bounds2 =
image->bounds().createIntersect(
gfx::Rect(
m_offsetX, m_offsetY,
bounds.w, bounds.h));
if (bounds.isEmpty())
return;
m_dstImage.reset(new WithImage(image));
m_bgcolor = doc->bgColor(cel->layer());
m_copy.reset(crop_image(image,
bounds2.x, bounds2.y, bounds2.w, bounds2.h, m_bgcolor));
}
void ClearRect::onExecute()
{
m_seq.execute(context());
if (m_dstImage)
clear();
}
void ClearRect::onUndo()
{
if (m_dstImage)
restore();
m_seq.undo();
}
void ClearRect::onRedo()
{
m_seq.redo();
if (m_dstImage)
clear();
}
void ClearRect::clear()
{
fill_rect(m_dstImage->image(),
m_offsetX, m_offsetY,
m_offsetX + m_copy->width() - 1,
m_offsetY + m_copy->height() - 1,
m_bgcolor);
}
void ClearRect::restore()
{
copy_image(m_dstImage->image(), m_copy.get(), m_offsetX, m_offsetY);
}
} // namespace cmd
} // namespace app

54
src/app/cmd/clear_rect.h Normal file
View File

@ -0,0 +1,54 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
#ifndef APP_CMD_CLEAR_RECT_H_INCLUDED
#define APP_CMD_CLEAR_RECT_H_INCLUDED
#pragma once
#include "app/cmd.h"
#include "app/cmd/with_image.h"
#include "app/cmd_sequence.h"
#include "base/unique_ptr.h"
#include "doc/image_ref.h"
#include "gfx/fwd.h"
namespace doc {
class Cel;
}
namespace app {
namespace cmd {
using namespace doc;
class ClearRect : public Cmd {
public:
ClearRect(Cel* cel, const gfx::Rect& bounds);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_seq.memSize() +
(m_copy ? m_copy->getMemSize(): 0);
}
private:
void clear();
void restore();
CmdSequence m_seq;
base::UniquePtr<WithImage> m_dstImage;
ImageRef m_copy;
int m_offsetX, m_offsetY;
color_t m_bgcolor;
};
} // namespace cmd
} // namespace app
#endif

View File

@ -10,12 +10,15 @@
#endif
#include "app/app.h"
#include "app/cmd/clear_rect.h"
#include "app/commands/command.h"
#include "app/commands/commands.h"
#include "app/console.h"
#include "app/context_access.h"
#include "app/modules/editors.h"
#include "app/settings/settings.h"
#include "app/tools/tool_box.h"
#include "app/transaction.h"
#include "app/ui/context_bar.h"
#include "app/ui/editor/editor.h"
#include "app/ui/editor/select_box_state.h"
@ -38,7 +41,7 @@ protected:
void onExecute(Context* context) override;
// SelectBoxDelegate impl
void onQuickboxEnd(const gfx::Rect& rect) override;
void onQuickboxEnd(const gfx::Rect& rect, ui::MouseButtons buttons) override;
private:
void createBrush(const Mask* mask);
@ -82,16 +85,28 @@ void NewBrushCommand::onExecute(Context* context)
Command* cmd =
CommandsModule::instance()->getCommandByName(CommandId::DeselectMask);
UIContext::instance()->executeCommand(cmd);
}
}
void NewBrushCommand::onQuickboxEnd(const gfx::Rect& rect)
void NewBrushCommand::onQuickboxEnd(const gfx::Rect& rect, ui::MouseButtons buttons)
{
Mask mask;
mask.replace(rect);
createBrush(&mask);
// If the right-button was used, we clear the selected area.
if (buttons & ui::kButtonRight) {
try {
ContextWriter writer(UIContext::instance(), 250);
Transaction transaction(writer.context(), "Clear");
transaction.execute(new cmd::ClearRect(writer.cel(), rect));
transaction.commit();
}
catch (const std::exception& ex) {
Console::showException(ex);
}
}
// Update the context bar
// TODO find a way to avoid all these singletons. Maybe a simple
// signal in the context like "brush has changed" could be enough.

View File

@ -97,7 +97,7 @@ bool SelectBoxState::onMouseUp(Editor* editor, MouseMessage* msg)
if (m_selectingBox) {
m_selectingBox = false;
if (m_delegate)
m_delegate->onQuickboxEnd(getBoxBounds());
m_delegate->onQuickboxEnd(getBoxBounds(), msg->buttons());
}
return StandbyState::onMouseUp(editor, msg);

View File

@ -12,6 +12,7 @@
#include "app/ui/editor/editor_decorator.h"
#include "app/ui/editor/ruler.h"
#include "app/ui/editor/standby_state.h"
#include "ui/mouse_buttons.h"
#include <vector>
@ -27,7 +28,7 @@ namespace app {
// Called only in QUICKBOX mode, when the user released the mouse
// button.
virtual void onQuickboxEnd(const gfx::Rect& rect) { }
virtual void onQuickboxEnd(const gfx::Rect& rect, ui::MouseButtons buttons) { }
};
class SelectBoxState : public StandbyState