Filters: Use the selected cels range instead of target buttons

With this commit we've definitely removed the target buttons to apply a
filter in current cel/layer/frame (which never make too much sense to
the end-user), and now we can just select the range of
layers/frames/cels where we want to apply the filter (like Flip and
Rotate commands that were already working in this way).
This commit is contained in:
David Capello 2018-03-13 17:05:14 -03:00
parent 5ccdacc9de
commit 245285f84e
10 changed files with 27 additions and 235 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -240,10 +240,6 @@
<part id="pal_presets" x="160" y="200" w="5" h="5" />
<part id="pal_options" x="168" y="200" w="5" h="5" />
<part id="pal_resize" x="176" y="200" w="5" h="5" />
<part id="target_one" x="144" y="224" w="32" h="16" />
<part id="target_frames" x="176" y="224" w="32" h="16" />
<part id="target_layers" x="208" y="224" w="32" h="16" />
<part id="target_frames_layers" x="240" y="224" w="32" h="16" />
<part id="selection_replace" x="176" y="160" w="7" h="7" />
<part id="selection_add" x="184" y="160" w="7" h="7" />
<part id="selection_subtract" x="192" y="160" w="7" h="7" />

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2017 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -10,6 +10,7 @@
#include "app/commands/filters/filter_manager_impl.h"
#include "app/app.h"
#include "app/cmd/copy_region.h"
#include "app/cmd/patch_cel.h"
#include "app/cmd/set_palette.h"
@ -23,10 +24,12 @@
#include "app/ui/color_bar.h"
#include "app/ui/editor/editor.h"
#include "app/ui/palette_view.h"
#include "app/ui/timeline/timeline.h"
#include "app/util/range_utils.h"
#include "doc/algorithm/shrink_bounds.h"
#include "doc/cel.h"
#include "doc/cel.h"
#include "doc/image.h"
#include "doc/images_collector.h"
#include "doc/layer.h"
#include "doc/mask.h"
#include "doc/site.h"
@ -228,13 +231,17 @@ void FilterManagerImpl::applyToTarget()
const bool paletteChange = paletteHasChanged();
bool cancelled = false;
ImagesCollector images((m_target & TARGET_ALL_LAYERS ?
m_site.sprite()->root():
m_site.layer()),
m_site.frame(),
(m_target & TARGET_ALL_FRAMES) == TARGET_ALL_FRAMES,
true); // we will write in each image
if (images.empty() && !paletteChange) {
CelList cels;
auto range = App::instance()->timeline()->range();
if (range.enabled())
cels = get_unlocked_unique_cels(m_site.sprite(), range);
else if (m_site.cel() &&
m_site.layer() &&
m_site.layer()->isEditable()) {
cels.push_back(m_site.cel());
}
if (cels.empty() && !paletteChange) {
// We don't have images/palette changes to do (there will not be a
// transaction).
return;
@ -246,7 +253,7 @@ void FilterManagerImpl::applyToTarget()
m_transaction.reset(new Transaction(writer.context(), m_filter->getName(), ModifyDocument));
m_progressBase = 0.0f;
m_progressWidth = 1.0f / images.size();
m_progressWidth = (cels.size() > 0 ? 1.0f / cels.size(): 1.0f);
std::set<ObjectId> visited;
@ -260,15 +267,15 @@ void FilterManagerImpl::applyToTarget()
}
// For each target image
for (auto it = images.begin();
it != images.end() && !cancelled;
for (auto it = cels.begin();
it != cels.end() && !cancelled;
++it) {
Image* image = it->image();
Image* image = (*it)->image();
// Avoid applying the filter two times to the same image
if (visited.find(image->id()) == visited.end()) {
visited.insert(image->id());
applyToCel(it->cel());
applyToCel(*it);
}
// Is there a delegate to know if the process was cancelled by the user?

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2017 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -37,7 +37,6 @@ FilterTargetButtons::FilterTargetButtons(int imgtype, bool withChannels)
, m_alpha(nullptr)
, m_gray(nullptr)
, m_index(nullptr)
, m_cels(nullptr)
{
setMultipleSelection(true);
addChild(&m_tooltips);
@ -62,17 +61,10 @@ FilterTargetButtons::FilterTargetButtons(int imgtype, bool withChannels)
break;
}
}
// Create the button to select which cels will be modified by the
// filter.
m_cels = addItem(getCelsIcon(), 4, 1);
}
void FilterTargetButtons::setTarget(int target)
{
m_target &= (TARGET_ALL_FRAMES | TARGET_ALL_LAYERS);
m_target |= (target & ~(TARGET_ALL_FRAMES | TARGET_ALL_LAYERS));
selectTargetButton(m_red, TARGET_RED_CHANNEL);
selectTargetButton(m_green, TARGET_GREEN_CHANNEL);
selectTargetButton(m_blue, TARGET_BLUE_CHANNEL);
@ -91,32 +83,12 @@ void FilterTargetButtons::selectTargetButton(Item* item, Target specificTarget)
void FilterTargetButtons::updateFromTarget()
{
m_cels->setIcon(getCelsIcon());
updateComponentTooltip(m_red, "Red", BOTTOM);
updateComponentTooltip(m_green, "Green", BOTTOM);
updateComponentTooltip(m_blue, "Blue", BOTTOM);
updateComponentTooltip(m_gray, "Gray", BOTTOM);
updateComponentTooltip(m_alpha, "Alpha", BOTTOM);
updateComponentTooltip(m_index, "Index", LEFT);
const char* celsTooltip = "";
switch (m_target & (TARGET_ALL_FRAMES | TARGET_ALL_LAYERS)) {
case 0:
celsTooltip = "Apply to the active frame/layer (the active cel)";
break;
case TARGET_ALL_FRAMES:
celsTooltip = "Apply to all frames in the active layer";
break;
case TARGET_ALL_LAYERS:
celsTooltip = "Apply to all layers in the active frame";
break;
case TARGET_ALL_FRAMES | TARGET_ALL_LAYERS:
celsTooltip = "Apply to all cels in the sprite";
break;
}
m_tooltips.addTooltipFor(m_cels, celsTooltip, LEFT);
}
void FilterTargetButtons::updateComponentTooltip(Item* item, const char* channelName, int align)
@ -133,7 +105,7 @@ void FilterTargetButtons::updateComponentTooltip(Item* item, const char* channel
void FilterTargetButtons::onItemChange(Item* item)
{
ButtonSet::onItemChange(item);
Target flags = (m_target & (TARGET_ALL_FRAMES | TARGET_ALL_LAYERS));
Target flags = m_target;
if (m_index && item && item->isSelected()) {
if (item == m_index) {
@ -157,23 +129,6 @@ void FilterTargetButtons::onItemChange(Item* item)
if (m_index && m_index->isSelected()) flags |= TARGET_INDEX_CHANNEL;
if (m_alpha && m_alpha->isSelected()) flags |= TARGET_ALPHA_CHANNEL;
if (m_cels->isSelected()) {
m_cels->setSelected(false);
// Rotate cels target
if (flags & TARGET_ALL_FRAMES) {
flags &= ~TARGET_ALL_FRAMES;
if (flags & TARGET_ALL_LAYERS)
flags &= ~TARGET_ALL_LAYERS;
else
flags |= TARGET_ALL_LAYERS;
}
else {
flags |= TARGET_ALL_FRAMES;
}
}
if (m_target != flags) {
m_target = flags;
updateFromTarget();
@ -181,20 +136,4 @@ void FilterTargetButtons::onItemChange(Item* item)
}
}
SkinPartPtr FilterTargetButtons::getCelsIcon() const
{
SkinTheme* theme = SkinTheme::instance();
if (m_target & TARGET_ALL_FRAMES) {
return (m_target & TARGET_ALL_LAYERS) ?
theme->parts.targetFramesLayers():
theme->parts.targetFrames();
}
else {
return (m_target & TARGET_ALL_LAYERS) ?
theme->parts.targetLayers():
theme->parts.targetOne();
}
}
} // namespace app

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2016, 2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -41,7 +41,6 @@ namespace app {
void selectTargetButton(Item* item, Target specificTarget);
void updateFromTarget();
void updateComponentTooltip(Item* item, const char* channelName, int align);
skin::SkinPartPtr getCelsIcon() const;
Target m_target;
Item* m_red;
@ -50,7 +49,6 @@ namespace app {
Item* m_alpha;
Item* m_gray;
Item* m_index;
Item* m_cels;
ui::TooltipManager m_tooltips;
};

View File

@ -1,5 +1,5 @@
# Aseprite Document Library
# Copyright (C) 2001-2017 David Capello
# Copyright (C) 2001-2018 David Capello
if(WIN32)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
@ -41,7 +41,6 @@ add_library(doc-lib
image.cpp
image_impl.cpp
image_io.cpp
images_collector.cpp
layer.cpp
layer_io.cpp
layer_list.cpp

View File

@ -1,70 +0,0 @@
// Aseprite Document Library
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "doc/cel.h"
#include "doc/image.h"
#include "doc/images_collector.h"
#include "doc/layer.h"
#include "doc/mask.h"
#include "doc/sprite.h"
namespace doc {
ImagesCollector::ImagesCollector(Layer* layer,
frame_t frame,
bool allFrames,
bool forEdit)
: m_allFrames(allFrames)
, m_forEdit(forEdit)
{
collectFromLayer(layer, frame);
}
void ImagesCollector::collectFromLayer(Layer* layer, frame_t frame)
{
const Sprite* sprite = layer->sprite();
if (!layer->isVisible())
return;
if (m_forEdit && !layer->isEditable())
return;
switch (layer->type()) {
case ObjectType::LayerImage: {
if (m_allFrames) {
for (frame_t frame(0); frame<sprite->totalFrames(); ++frame) {
if (Cel* cel = layer->cel(frame))
collectImage(layer, cel);
}
}
else {
if (Cel* cel = layer->cel(frame))
collectImage(layer, cel);
}
break;
}
case ObjectType::LayerGroup: {
for (Layer* child : static_cast<LayerGroup*>(layer)->layers())
collectFromLayer(child, frame);
break;
}
}
}
void ImagesCollector::collectImage(Layer* layer, Cel* cel)
{
m_items.push_back(Item(layer, cel, cel->image()));
}
} // namespace doc

View File

@ -1,74 +0,0 @@
// Aseprite Document Library
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef DOC_IMAGES_REF_H_INCLUDED
#define DOC_IMAGES_REF_H_INCLUDED
#pragma once
#include "doc/frame.h"
#include <list>
namespace doc {
class Sprite;
class Image;
class Layer;
class Cel;
// Collects images from a sprite
class ImagesCollector {
public:
class Item {
public:
Item(Layer* layer, Cel* cel, Image* image)
: m_layer(layer)
, m_cel(cel)
, m_image(image)
{ }
Layer* layer() const { return m_layer; }
Cel* cel() const { return m_cel; }
Image* image() const { return m_image; }
private:
Layer* m_layer;
Cel* m_cel;
Image* m_image;
};
typedef std::list<Item> Items;
typedef std::list<Item>::iterator ItemsIterator;
// Creates a collection of images from the specified sprite.
// Parameters:
// * allFrames: True if you want to collect images from all frames
// or false if you need images from the given "frame" param.
// * forEdit: True if you will modify the images (it is used to avoid
// returning images from layers which are read-only/write-locked).
ImagesCollector(Layer* layer,
frame_t frame,
bool allFrames,
bool forEdit);
ItemsIterator begin() { return m_items.begin(); }
ItemsIterator end() { return m_items.end(); }
std::size_t size() const { return m_items.size(); }
bool empty() const { return m_items.empty(); }
private:
void collectFromLayer(Layer* layer, frame_t frame);
void collectImage(Layer* layer, Cel* cel);
Items m_items;
bool m_allFrames;
bool m_forEdit;
};
} // namespace doc
#endif

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -14,8 +14,6 @@
#define TARGET_ALPHA_CHANNEL 8
#define TARGET_GRAY_CHANNEL 16
#define TARGET_INDEX_CHANNEL 32
#define TARGET_ALL_FRAMES 64
#define TARGET_ALL_LAYERS 128
#define TARGET_ALL_CHANNELS \
(TARGET_RED_CHANNEL | \

View File

@ -1,5 +1,5 @@
// Aseprite Render Library
// Copyright (c) 2001-2017 David Capello
// Copyright (c) 2001-2018 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -12,7 +12,6 @@
#include "base/unique_ptr.h"
#include "doc/image_impl.h"
#include "doc/images_collector.h"
#include "doc/layer.h"
#include "doc/palette.h"
#include "doc/primitives.h"