mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-06 06:50:07 +00:00
Add command to fill selection with foreground color (F key, related to #1387)
This commit is contained in:
parent
6ab467e5f9
commit
291e9c7dde
@ -18,7 +18,7 @@
|
|||||||
<key command="ImportSpriteSheet" shortcut="Ctrl+I" mac="Cmd+I" />
|
<key command="ImportSpriteSheet" shortcut="Ctrl+I" mac="Cmd+I" />
|
||||||
<key command="ExportSpriteSheet" shortcut="Ctrl+E" mac="Cmd+E" />
|
<key command="ExportSpriteSheet" shortcut="Ctrl+E" mac="Cmd+E" />
|
||||||
<key command="RepeatLastExport" shortcut="Ctrl+Shift+X" mac="Cmd+Shift+X" />
|
<key command="RepeatLastExport" shortcut="Ctrl+Shift+X" mac="Cmd+Shift+X" />
|
||||||
<key command="AdvancedMode" shortcut="F" />
|
<key command="AdvancedMode" shortcut="Ctrl+F" />
|
||||||
<key command="DeveloperConsole" shortcut="F12" />
|
<key command="DeveloperConsole" shortcut="F12" />
|
||||||
<key command="Exit" win="Ctrl+Q" linux="Ctrl+Q" mac="Cmd+Q" />
|
<key command="Exit" win="Ctrl+Q" linux="Ctrl+Q" mac="Cmd+Q" />
|
||||||
<key command="Exit" win="Alt+F4" />
|
<key command="Exit" win="Alt+F4" />
|
||||||
@ -39,6 +39,7 @@
|
|||||||
<key command="Paste" shortcut="Shift+Ins" />
|
<key command="Paste" shortcut="Shift+Ins" />
|
||||||
<key command="Clear" shortcut="Del" />
|
<key command="Clear" shortcut="Del" />
|
||||||
<key command="Clear" shortcut="Backspace" />
|
<key command="Clear" shortcut="Backspace" />
|
||||||
|
<key command="Fill" shortcut="F" />
|
||||||
<key command="Flip" shortcut="Shift+H">
|
<key command="Flip" shortcut="Shift+H">
|
||||||
<param name="target" value="mask" />
|
<param name="target" value="mask" />
|
||||||
<param name="orientation" value="horizontal" />
|
<param name="orientation" value="horizontal" />
|
||||||
@ -591,6 +592,8 @@
|
|||||||
<item command="Paste" text="@.edit_paste" />
|
<item command="Paste" text="@.edit_paste" />
|
||||||
<item command="Clear" text="@.edit_clear" />
|
<item command="Clear" text="@.edit_clear" />
|
||||||
<separator />
|
<separator />
|
||||||
|
<item command="Fill" text="@.edit_fill" />
|
||||||
|
<separator />
|
||||||
<menu text="@.edit_rotate">
|
<menu text="@.edit_rotate">
|
||||||
<item command="Rotate" text="@.edit_rotate_180">
|
<item command="Rotate" text="@.edit_rotate_180">
|
||||||
<param name="target" value="mask" />
|
<param name="target" value="mask" />
|
||||||
|
@ -228,6 +228,7 @@ DuplicateView = Duplicate View
|
|||||||
Exit = Exit
|
Exit = Exit
|
||||||
ExportSpriteSheet = Export Sprite Sheet
|
ExportSpriteSheet = Export Sprite Sheet
|
||||||
Eyedropper = Eyedropper
|
Eyedropper = Eyedropper
|
||||||
|
Fill = Fill Selection with Foreground Color
|
||||||
FitScreen = Fit on Screen
|
FitScreen = Fit on Screen
|
||||||
FlattenLayers = Flatten Layers
|
FlattenLayers = Flatten Layers
|
||||||
Flip = Flip {0} {1}
|
Flip = Flip {0} {1}
|
||||||
@ -636,6 +637,7 @@ edit_copy = &Copy
|
|||||||
edit_copy_merged = Copy Mer&ged
|
edit_copy_merged = Copy Mer&ged
|
||||||
edit_paste = &Paste
|
edit_paste = &Paste
|
||||||
edit_clear = &Delete
|
edit_clear = &Delete
|
||||||
|
edit_fill = &Fill
|
||||||
edit_rotate = R&otate
|
edit_rotate = R&otate
|
||||||
edit_rotate_180 = &180
|
edit_rotate_180 = &180
|
||||||
edit_rotate_90cw = &90 CW
|
edit_rotate_90cw = &90 CW
|
||||||
@ -661,7 +663,7 @@ edit_fx_convolution_matrix = Convolution &Matrix...
|
|||||||
edit_fx_despeckle = &Despeckle (Median Filter)...
|
edit_fx_despeckle = &Despeckle (Median Filter)...
|
||||||
edit_insert_text = Insert Text
|
edit_insert_text = Insert Text
|
||||||
edit_keyboard_shortcuts = &Keyboard Shortcuts...
|
edit_keyboard_shortcuts = &Keyboard Shortcuts...
|
||||||
edit_preferences = Pre&ferences...
|
edit_preferences = Preferences&...
|
||||||
sprite = &Sprite
|
sprite = &Sprite
|
||||||
sprite_properties = &Properties...
|
sprite_properties = &Properties...
|
||||||
sprite_color_mode = Color &Mode
|
sprite_color_mode = Color &Mode
|
||||||
|
@ -196,6 +196,7 @@ if(ENABLE_UI)
|
|||||||
commands/cmd_exit.cpp
|
commands/cmd_exit.cpp
|
||||||
commands/cmd_export_sprite_sheet.cpp
|
commands/cmd_export_sprite_sheet.cpp
|
||||||
commands/cmd_eyedropper.cpp
|
commands/cmd_eyedropper.cpp
|
||||||
|
commands/cmd_fill.cpp
|
||||||
commands/cmd_fit_screen.cpp
|
commands/cmd_fit_screen.cpp
|
||||||
commands/cmd_flatten_layers.cpp
|
commands/cmd_flatten_layers.cpp
|
||||||
commands/cmd_flip.cpp
|
commands/cmd_flip.cpp
|
||||||
@ -390,6 +391,7 @@ if(ENABLE_UI)
|
|||||||
ui_context.cpp
|
ui_context.cpp
|
||||||
util/clipboard.cpp
|
util/clipboard.cpp
|
||||||
util/clipboard_native.cpp
|
util/clipboard_native.cpp
|
||||||
|
util/fill_selection.cpp
|
||||||
widget_loader.cpp)
|
widget_loader.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "app/cmd/clear_cel.h"
|
#include "app/cmd/clear_cel.h"
|
||||||
#include "app/document.h"
|
#include "app/document.h"
|
||||||
|
#include "app/util/fill_selection.h"
|
||||||
#include "doc/cel.h"
|
#include "doc/cel.h"
|
||||||
#include "doc/image_impl.h"
|
#include "doc/image_impl.h"
|
||||||
#include "doc/layer.h"
|
#include "doc/layer.h"
|
||||||
@ -35,18 +36,18 @@ ClearMask::ClearMask(Cel* cel)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Image* image = (cel ? cel->image(): NULL);
|
Image* image = cel->image();
|
||||||
|
assert(image);
|
||||||
if (!image)
|
if (!image)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Mask* mask = doc->mask();
|
Mask* mask = doc->mask();
|
||||||
m_offsetX = mask->bounds().x - cel->x();
|
m_offset = mask->bounds().origin() - cel->position();
|
||||||
m_offsetY = mask->bounds().y - cel->y();
|
|
||||||
|
|
||||||
gfx::Rect bounds =
|
gfx::Rect bounds =
|
||||||
image->bounds().createIntersection(
|
image->bounds().createIntersection(
|
||||||
gfx::Rect(
|
gfx::Rect(
|
||||||
m_offsetX, m_offsetY,
|
m_offset.x, m_offset.y,
|
||||||
mask->bounds().w, mask->bounds().h));
|
mask->bounds().w, mask->bounds().h));
|
||||||
if (bounds.isEmpty())
|
if (bounds.isEmpty())
|
||||||
return;
|
return;
|
||||||
@ -88,27 +89,7 @@ void ClearMask::clear()
|
|||||||
app::Document* doc = static_cast<app::Document*>(cel->document());
|
app::Document* doc = static_cast<app::Document*>(cel->document());
|
||||||
Mask* mask = doc->mask();
|
Mask* mask = doc->mask();
|
||||||
|
|
||||||
ASSERT(mask->bitmap());
|
fill_selection(image, m_offset, mask, m_bgcolor);
|
||||||
if (!mask->bitmap())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const LockImageBits<BitmapTraits> maskBits(mask->bitmap());
|
|
||||||
LockImageBits<BitmapTraits>::const_iterator it = maskBits.begin();
|
|
||||||
|
|
||||||
// Clear the masked zones
|
|
||||||
int u, v;
|
|
||||||
for (v=0; v<mask->bounds().h; ++v) {
|
|
||||||
for (u=0; u<mask->bounds().w; ++u, ++it) {
|
|
||||||
ASSERT(it != maskBits.end());
|
|
||||||
if (*it) {
|
|
||||||
put_pixel(image,
|
|
||||||
u + m_offsetX,
|
|
||||||
v + m_offsetY, m_bgcolor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(it == maskBits.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearMask::restore()
|
void ClearMask::restore()
|
||||||
|
@ -40,7 +40,7 @@ namespace cmd {
|
|||||||
CmdSequence m_seq;
|
CmdSequence m_seq;
|
||||||
base::UniquePtr<WithImage> m_dstImage;
|
base::UniquePtr<WithImage> m_dstImage;
|
||||||
ImageRef m_copy;
|
ImageRef m_copy;
|
||||||
int m_offsetX, m_offsetY;
|
gfx::Point m_offset;
|
||||||
int m_boundsX, m_boundsY;
|
int m_boundsX, m_boundsY;
|
||||||
color_t m_bgcolor;
|
color_t m_bgcolor;
|
||||||
};
|
};
|
||||||
|
113
src/app/commands/cmd_fill.cpp
Normal file
113
src/app/commands/cmd_fill.cpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2018 David Capello
|
||||||
|
//
|
||||||
|
// This program is distributed under the terms of
|
||||||
|
// the End-User License Agreement for Aseprite.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/app.h"
|
||||||
|
#include "app/cmd/clear_mask.h"
|
||||||
|
#include "app/cmd/trim_cel.h"
|
||||||
|
#include "app/color_utils.h"
|
||||||
|
#include "app/commands/command.h"
|
||||||
|
#include "app/context_access.h"
|
||||||
|
#include "app/modules/editors.h"
|
||||||
|
#include "app/pref/preferences.h"
|
||||||
|
#include "app/transaction.h"
|
||||||
|
#include "app/ui/editor/editor.h"
|
||||||
|
#include "app/util/expand_cel_canvas.h"
|
||||||
|
#include "app/util/fill_selection.h"
|
||||||
|
#include "doc/mask.h"
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
class FillCommand : public Command {
|
||||||
|
public:
|
||||||
|
FillCommand();
|
||||||
|
Command* clone() const override { return new FillCommand(*this); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool onEnabled(Context* ctx) override;
|
||||||
|
void onExecute(Context* ctx) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
FillCommand::FillCommand()
|
||||||
|
: Command(CommandId::Fill(), CmdUIOnlyFlag)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FillCommand::onEnabled(Context* ctx)
|
||||||
|
{
|
||||||
|
if (ctx->checkFlags(ContextFlags::ActiveDocumentIsWritable |
|
||||||
|
ContextFlags::ActiveLayerIsVisible |
|
||||||
|
ContextFlags::ActiveLayerIsEditable |
|
||||||
|
ContextFlags::ActiveLayerIsImage)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (current_editor &&
|
||||||
|
current_editor->isMovingPixels()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillCommand::onExecute(Context* ctx)
|
||||||
|
{
|
||||||
|
ContextWriter writer(ctx);
|
||||||
|
Site site = *writer.site();
|
||||||
|
Document* doc = (app::Document*)site.document();
|
||||||
|
Sprite* sprite = site.sprite();
|
||||||
|
Cel* cel = site.cel();
|
||||||
|
Mask* mask = doc->mask();
|
||||||
|
if (!doc || !sprite || !cel || !mask ||
|
||||||
|
!doc->isMaskVisible())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Preferences& pref = Preferences::instance();
|
||||||
|
app::Color color = pref.colorBar.fgColor();
|
||||||
|
|
||||||
|
{
|
||||||
|
Transaction transaction(writer.context(), "Fill Selection with Foreground Color");
|
||||||
|
{
|
||||||
|
ExpandCelCanvas expand(
|
||||||
|
site, cel->layer(),
|
||||||
|
TiledMode::NONE, transaction,
|
||||||
|
ExpandCelCanvas::None);
|
||||||
|
|
||||||
|
gfx::Region rgn(sprite->bounds() |
|
||||||
|
mask->bounds());
|
||||||
|
expand.validateDestCanvas(rgn);
|
||||||
|
|
||||||
|
const gfx::Point offset = (mask->bounds().origin()
|
||||||
|
- expand.getCel()->position());
|
||||||
|
|
||||||
|
fill_selection(expand.getDestCanvas(),
|
||||||
|
offset,
|
||||||
|
mask,
|
||||||
|
color_utils::color_for_layer(color,
|
||||||
|
cel->layer()));
|
||||||
|
|
||||||
|
expand.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the cel wasn't deleted by cmd::ClearMask, we trim it.
|
||||||
|
cel = ctx->activeSite().cel();
|
||||||
|
if (cel && cel->layer()->isTransparent())
|
||||||
|
transaction.execute(new cmd::TrimCel(cel));
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
doc->notifyGeneralUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
Command* CommandFactory::createFillCommand()
|
||||||
|
{
|
||||||
|
return new FillCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace app
|
@ -48,6 +48,7 @@ FOR_EACH_COMMAND(DuplicateView)
|
|||||||
FOR_EACH_COMMAND(Exit)
|
FOR_EACH_COMMAND(Exit)
|
||||||
FOR_EACH_COMMAND(ExportSpriteSheet)
|
FOR_EACH_COMMAND(ExportSpriteSheet)
|
||||||
FOR_EACH_COMMAND(Eyedropper)
|
FOR_EACH_COMMAND(Eyedropper)
|
||||||
|
FOR_EACH_COMMAND(Fill)
|
||||||
FOR_EACH_COMMAND(FitScreen)
|
FOR_EACH_COMMAND(FitScreen)
|
||||||
FOR_EACH_COMMAND(FlattenLayers)
|
FOR_EACH_COMMAND(FlattenLayers)
|
||||||
FOR_EACH_COMMAND(Flip)
|
FOR_EACH_COMMAND(Flip)
|
||||||
|
48
src/app/util/fill_selection.cpp
Normal file
48
src/app/util/fill_selection.cpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2018 David Capello
|
||||||
|
//
|
||||||
|
// This program is distributed under the terms of
|
||||||
|
// the End-User License Agreement for Aseprite.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/util/fill_selection.h"
|
||||||
|
|
||||||
|
#include "doc/image_impl.h"
|
||||||
|
#include "doc/mask.h"
|
||||||
|
#include "doc/primitives.h"
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
using namespace doc;
|
||||||
|
|
||||||
|
void fill_selection(Image* image,
|
||||||
|
const gfx::Point& offset,
|
||||||
|
const Mask* mask,
|
||||||
|
const color_t color)
|
||||||
|
{
|
||||||
|
ASSERT(mask->bitmap());
|
||||||
|
if (!mask->bitmap())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const LockImageBits<BitmapTraits> maskBits(mask->bitmap());
|
||||||
|
LockImageBits<BitmapTraits>::const_iterator it = maskBits.begin();
|
||||||
|
|
||||||
|
const gfx::Rect maskBounds = mask->bounds();
|
||||||
|
for (int v=0; v<maskBounds.h; ++v) {
|
||||||
|
for (int u=0; u<maskBounds.w; ++u, ++it) {
|
||||||
|
ASSERT(it != maskBits.end());
|
||||||
|
if (*it) {
|
||||||
|
put_pixel(image,
|
||||||
|
u + offset.x,
|
||||||
|
v + offset.y, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(it == maskBits.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace app
|
28
src/app/util/fill_selection.h
Normal file
28
src/app/util/fill_selection.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2018 David Capello
|
||||||
|
//
|
||||||
|
// This program is distributed under the terms of
|
||||||
|
// the End-User License Agreement for Aseprite.
|
||||||
|
|
||||||
|
#ifndef APP_UTIL_FILL_SELECTION_H_INCLUDED
|
||||||
|
#define APP_UTIL_FILL_SELECTION_H_INCLUDED
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "doc/color.h"
|
||||||
|
#include "gfx/point.h"
|
||||||
|
|
||||||
|
namespace doc {
|
||||||
|
class Image;
|
||||||
|
class Mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
void fill_selection(doc::Image* image,
|
||||||
|
const gfx::Point& offset,
|
||||||
|
const doc::Mask* mask,
|
||||||
|
const doc::color_t color);
|
||||||
|
|
||||||
|
} // namespace app
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user