mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-05 21:57:20 +00:00
Creating a brush with right-click clear the selected region with bg color (#154)
This commit is contained in:
parent
51b6def023
commit
8f500178fc
@ -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
|
||||
|
87
src/app/cmd/clear_rect.cpp
Normal file
87
src/app/cmd/clear_rect.cpp
Normal 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
54
src/app/cmd/clear_rect.h
Normal 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
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user