Skip to content

Commit

Permalink
New option for paint bucket using all layers as reference/stop fill (fix
Browse files Browse the repository at this point in the history
  • Loading branch information
dacap committed May 3, 2016
1 parent aededaa commit 6dc9bb9
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 24 deletions.
5 changes: 5 additions & 0 deletions data/pref.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
<value id="IF_VISIBLE" value="1" />
<value id="ALWAYS" value="2" />
</enum>
<enum id="FillReferTo">
<value id="ACTIVE_LAYER" value="0" />
<value id="ALL_LAYERS" value="1" />
</enum>
<enum id="EyedropperChannel">
<value id="COLOR_ALPHA" value="0" />
<value id="COLOR" value="1" />
Expand Down Expand Up @@ -210,6 +214,7 @@
</section>
<section id="floodfill">
<option id="stop_at_grid" type="StopAtGrid" default="StopAtGrid::IF_VISIBLE" />
<option id="refer_to" type="FillReferTo" default="FillReferTo::ACTIVE_LAYER" />
</section>
</tool>

Expand Down
6 changes: 3 additions & 3 deletions src/app/tools/point_shapes.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 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
Expand Down Expand Up @@ -83,7 +83,7 @@ class FloodFillPointShape : public PointShape {

void transformPoint(ToolLoop* loop, int x, int y) override {
doc::algorithm::floodfill(
loop->getSrcImage(),
loop->getFloodFillSrcImage(),
(loop->useMask() ? loop->getMask(): nullptr),
x, y,
floodfillBounds(loop, x, y),
Expand All @@ -104,7 +104,7 @@ class FloodFillPointShape : public PointShape {
loop->sprite()->height());

bounds = bounds.createIntersection(
loop->getSrcImage()->bounds());
loop->getFloodFillSrcImage()->bounds());

// Limit the flood-fill to the current tile if the grid is visible.
if (loop->getStopAtGrid()) {
Expand Down
3 changes: 3 additions & 0 deletions src/app/tools/tool_loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ namespace app {
// Should return an image where we can read pixels (readonly image)
virtual const Image* getSrcImage() = 0;

// The image used to get get pixels in floodfill algorithm.
virtual const Image* getFloodFillSrcImage() = 0;

// Should return an image where we can write pixels
virtual Image* getDstImage() = 0;

Expand Down
63 changes: 45 additions & 18 deletions src/app/ui/context_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,28 +279,57 @@ class ContextBar::ContiguousField : public CheckBox
}
};

class ContextBar::StopAtGridField : public CheckBox
{
class ContextBar::PaintBucketSettingsField : public ButtonSet {
public:
StopAtGridField() : CheckBox("Stop at Grid") {
setup_mini_font(this);
}

void setStopAtGrid(bool state) {
setSelected(state);
PaintBucketSettingsField() : ButtonSet(1) {
SkinTheme* theme = SkinTheme::instance();
addItem(theme->parts.timelineGear());
}

protected:
void onClick(Event& ev) override {
CheckBox::onClick(ev);
void onItemChange(Item* item) override {
ButtonSet::onItemChange(item);
const gfx::Rect bounds = this->bounds();

Tool* tool = App::instance()->activeTool();
Preferences::instance().tool(tool).floodfill.stopAtGrid(
(isSelected() ? app::gen::StopAtGrid::IF_VISIBLE:
app::gen::StopAtGrid::NEVER));
auto& toolPref = Preferences::instance().tool(tool);

releaseFocus();
Menu menu;
MenuItem
stopAtGrid("Stop at Grid"),
activeLayer("Refer only active layer"),
allLayers("Refer visible layers");
menu.addChild(&stopAtGrid);
menu.addChild(new MenuSeparator());
menu.addChild(&activeLayer);
menu.addChild(&allLayers);

stopAtGrid.setSelected(
toolPref.floodfill.stopAtGrid() == app::gen::StopAtGrid::IF_VISIBLE);
activeLayer.setSelected(
toolPref.floodfill.referTo() == app::gen::FillReferTo::ACTIVE_LAYER);
allLayers.setSelected(
toolPref.floodfill.referTo() == app::gen::FillReferTo::ALL_LAYERS);

stopAtGrid.Click.connect(
[&]{
toolPref.floodfill.stopAtGrid(
toolPref.floodfill.stopAtGrid() == app::gen::StopAtGrid::IF_VISIBLE ?
app::gen::StopAtGrid::NEVER: app::gen::StopAtGrid::IF_VISIBLE);
});
activeLayer.Click.connect(
[&]{
toolPref.floodfill.referTo(app::gen::FillReferTo::ACTIVE_LAYER);
});
allLayers.Click.connect(
[&]{
toolPref.floodfill.referTo(app::gen::FillReferTo::ALL_LAYERS);
});

menu.showPopup(gfx::Point(bounds.x, bounds.y+bounds.h));
deselectItems();
}

};

class ContextBar::InkTypeField : public ButtonSet {
Expand Down Expand Up @@ -1286,7 +1315,7 @@ ContextBar::ContextBar()
addChild(m_toleranceLabel = new Label("Tolerance:"));
addChild(m_tolerance = new ToleranceField());
addChild(m_contiguous = new ContiguousField());
addChild(m_stopAtGrid = new StopAtGridField());
addChild(m_paintBucketSettings = new PaintBucketSettingsField());

addChild(m_inkType = new InkTypeField(this));
addChild(m_inkOpacityLabel = new Label("Opacity:"));
Expand Down Expand Up @@ -1506,8 +1535,6 @@ void ContextBar::updateForTool(tools::Tool* tool)
if (toolPref) {
m_tolerance->setTextf("%d", toolPref->tolerance());
m_contiguous->setSelected(toolPref->contiguous());
m_stopAtGrid->setSelected(
toolPref->floodfill.stopAtGrid() == app::gen::StopAtGrid::IF_VISIBLE ? true: false);

m_inkType->setInkTypeIcon(toolPref->ink());
m_inkOpacity->setTextf("%d", toolPref->opacity());
Expand Down Expand Up @@ -1590,7 +1617,7 @@ void ContextBar::updateForTool(tools::Tool* tool)
m_toleranceLabel->setVisible(hasTolerance);
m_tolerance->setVisible(hasTolerance);
m_contiguous->setVisible(hasTolerance);
m_stopAtGrid->setVisible(hasTolerance);
m_paintBucketSettings->setVisible(hasTolerance);
m_sprayBox->setVisible(hasSprayOptions);
m_selectionOptionsBox->setVisible(hasSelectOptions);
m_selectionMode->setVisible(true);
Expand Down
4 changes: 2 additions & 2 deletions src/app/ui/context_bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ namespace app {
class BrushSizeField;
class ToleranceField;
class ContiguousField;
class StopAtGridField;
class PaintBucketSettingsField;
class InkTypeField;
class InkOpacityField;
class InkShadesField;
Expand All @@ -115,7 +115,7 @@ namespace app {
ui::Label* m_toleranceLabel;
ToleranceField* m_tolerance;
ContiguousField* m_contiguous;
StopAtGridField* m_stopAtGrid;
PaintBucketSettingsField* m_paintBucketSettings;
InkTypeField* m_inkType;
ui::Label* m_inkOpacityLabel;
InkOpacityField* m_inkOpacity;
Expand Down
30 changes: 30 additions & 0 deletions src/app/ui/editor/tool_loop_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "doc/palette_picks.h"
#include "doc/remap.h"
#include "doc/sprite.h"
#include "render/render.h"
#include "ui/ui.h"

namespace app {
Expand Down Expand Up @@ -269,6 +270,7 @@ class ToolLoopImpl : public ToolLoopBase {
bool m_canceled;
Transaction m_transaction;
ExpandCelCanvas m_expandCelCanvas;
Image* m_floodfillSrcImage;

public:
ToolLoopImpl(Editor* editor,
Expand Down Expand Up @@ -344,6 +346,32 @@ class ToolLoopImpl : public ToolLoopBase {
m_maskOrigin = (!m_mask->isEmpty() ? gfx::Point(m_mask->bounds().x-m_celOrigin.x,
m_mask->bounds().y-m_celOrigin.y):
gfx::Point(0, 0));

// Prepare a special image for floodfill when it's configured to
// stop using all visible layers.
if (m_pointShape->isFloodFill() &&
m_toolPref.floodfill.referTo() == gen::FillReferTo::ALL_LAYERS) {
m_floodfillSrcImage = Image::create(m_sprite->pixelFormat(),
m_sprite->width(),
m_sprite->height());

m_floodfillSrcImage->clear(m_sprite->transparentColor());

render::Render().renderSprite(
m_floodfillSrcImage,
m_sprite,
m_frame,
gfx::Clip(m_sprite->bounds()),
render::Zoom(1, 1));
}
else {
m_floodfillSrcImage = const_cast<Image*>(getSrcImage());
}
}

~ToolLoopImpl() {
if (m_floodfillSrcImage != getSrcImage())
delete m_floodfillSrcImage;
}

// IToolLoop interface
Expand Down Expand Up @@ -394,6 +422,7 @@ class ToolLoopImpl : public ToolLoopBase {
}

const Image* getSrcImage() override { return m_expandCelCanvas.getSourceCanvas(); }
const Image* getFloodFillSrcImage() override { return m_floodfillSrcImage; }
Image* getDstImage() override { return m_expandCelCanvas.getDestCanvas(); }
void validateSrcImage(const gfx::Region& rgn) override {
m_expandCelCanvas.validateSourceCanvas(rgn);
Expand Down Expand Up @@ -541,6 +570,7 @@ class PreviewToolLoopImpl : public ToolLoopBase {
// IToolLoop interface
void dispose() override { }
const Image* getSrcImage() override { return m_image; }
const Image* getFloodFillSrcImage() override { return m_image; }
Image* getDstImage() override { return m_image; }
void validateSrcImage(const gfx::Region& rgn) override { }
void validateDstImage(const gfx::Region& rgn) override { }
Expand Down
1 change: 0 additions & 1 deletion src/app/util/expand_cel_canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include "doc/primitives.h"
#include "doc/site.h"
#include "doc/sprite.h"
#include "render/render.h"

namespace {

Expand Down

0 comments on commit 6dc9bb9

Please sign in to comment.