mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-11 09:40:42 +00:00
Add possibility to select any matrix to run the OutlineFilter
This commit is contained in:
parent
be74710067
commit
8551fbda26
Binary file not shown.
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@ -412,6 +412,12 @@
|
||||
<part id="folder_icon_small" x="144" y="272" w="10" h="8" />
|
||||
<part id="folder_icon_big" x="176" y="272" w="32" h="32" />
|
||||
<part id="folder_icon_medium" x="160" y="272" w="16" h="16" />
|
||||
<part id="outline_circle" x="144" y="224" w="13" h="15" />
|
||||
<part id="outline_square" x="160" y="224" w="13" h="15" />
|
||||
<part id="outline_horizontal" x="176" y="224" w="13" h="15" />
|
||||
<part id="outline_vertical" x="192" y="224" w="13" h="15" />
|
||||
<part id="outline_empty_pixel" x="208" y="224" w="5" h="5" />
|
||||
<part id="outline_full_pixel" x="214" y="224" w="5" h="5" />
|
||||
</parts>
|
||||
<styles>
|
||||
<style id="box" />
|
||||
|
@ -10,10 +10,27 @@
|
||||
</grid>
|
||||
<hbox>
|
||||
<vbox>
|
||||
<radio id="circle" text="@.circle" group="1" />
|
||||
<radio id="square" text="@.square" group="1" />
|
||||
<radio id="horizontal" text="@.horizontal" group="1" />
|
||||
<radio id="vertical" text="@.vertical" group="1" />
|
||||
<hbox>
|
||||
<buttonset id="outline_type" columns="2">
|
||||
<item icon="outline_circle" tooltip="@.circle" tooltip_dir="right" />
|
||||
<item icon="outline_square" tooltip="@.square" tooltip_dir="left" />
|
||||
<item icon="outline_horizontal" tooltip="@.horizontal" tooltip_dir="right" />
|
||||
<item icon="outline_vertical" tooltip="@.vertical" tooltip_dir="left" />
|
||||
</buttonset>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<buttonset id="outline_matrix" columns="3">
|
||||
<item icon="outline_empty_pixel" />
|
||||
<item icon="outline_empty_pixel" />
|
||||
<item icon="outline_empty_pixel" />
|
||||
<item icon="outline_empty_pixel" />
|
||||
<item icon="outline_empty_pixel" />
|
||||
<item icon="outline_empty_pixel" />
|
||||
<item icon="outline_empty_pixel" />
|
||||
<item icon="outline_empty_pixel" />
|
||||
<item icon="outline_empty_pixel" />
|
||||
</buttonset>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox>
|
||||
<radio id="outside" text="@.outside" group="2" />
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/ui/color_bar.h"
|
||||
#include "app/ui/color_button.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "base/bind.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/mask.h"
|
||||
@ -34,6 +35,10 @@
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace app::skin;
|
||||
|
||||
enum { CIRCLE, SQUARE, HORZ, VERT };
|
||||
|
||||
static const char* ConfigSection = "Outline";
|
||||
|
||||
// Wrapper for ReplaceColorFilter to handle colors in an easy way
|
||||
@ -77,22 +82,43 @@ public:
|
||||
m_panel.bgColor()->setColor(m_filter.bgColor());
|
||||
m_panel.outside()->setSelected(m_filter.place() == OutlineFilter::Place::Outside);
|
||||
m_panel.inside()->setSelected(m_filter.place() == OutlineFilter::Place::Inside);
|
||||
m_panel.circle()->setSelected(m_filter.shape() == OutlineFilter::Shape::Circle);
|
||||
m_panel.square()->setSelected(m_filter.shape() == OutlineFilter::Shape::Square);
|
||||
m_panel.horizontal()->setSelected(m_filter.shape() == OutlineFilter::Shape::Horizontal);
|
||||
m_panel.vertical()->setSelected(m_filter.shape() == OutlineFilter::Shape::Vertical);
|
||||
updateButtonsFromMatrix();
|
||||
|
||||
m_panel.color()->Change.connect(&OutlineWindow::onColorChange, this);
|
||||
m_panel.bgColor()->Change.connect(&OutlineWindow::onBgColorChange, this);
|
||||
m_panel.outside()->Click.connect([this](ui::Event&){ onPlaceChange(OutlineFilter::Place::Outside); });
|
||||
m_panel.inside()->Click.connect([this](ui::Event&){ onPlaceChange(OutlineFilter::Place::Inside); });
|
||||
m_panel.circle()->Click.connect([this](ui::Event&){ onShapeChange(OutlineFilter::Shape::Circle); });
|
||||
m_panel.square()->Click.connect([this](ui::Event&){ onShapeChange(OutlineFilter::Shape::Square); });
|
||||
m_panel.horizontal()->Click.connect([this](ui::Event&){ onShapeChange(OutlineFilter::Shape::Horizontal); });
|
||||
m_panel.vertical()->Click.connect([this](ui::Event&){ onShapeChange(OutlineFilter::Shape::Vertical); });
|
||||
m_panel.outlineType()->ItemChange.connect([this](ButtonSet::Item*){ onMatrixTypeChange(); });
|
||||
m_panel.outlineMatrix()->ItemChange.connect(
|
||||
[this](ButtonSet::Item* item){
|
||||
onMatrixPixelChange(m_panel.outlineMatrix()->getItemIndex(item));
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
void updateButtonsFromMatrix() {
|
||||
const OutlineFilter::Matrix matrix = m_filter.matrix();
|
||||
|
||||
int commonMatrix = -1;
|
||||
switch (matrix) {
|
||||
case OutlineFilter::kCircleMatrix: commonMatrix = CIRCLE; break;
|
||||
case OutlineFilter::kSquareMatrix: commonMatrix = SQUARE; break;
|
||||
case OutlineFilter::kHorizontalMatrix: commonMatrix = HORZ; break;
|
||||
case OutlineFilter::kVerticalMatrix: commonMatrix = VERT; break;
|
||||
}
|
||||
m_panel.outlineType()->setSelectedItem(commonMatrix, false);
|
||||
|
||||
auto theme = static_cast<SkinTheme*>(this->theme());
|
||||
auto emptyIcon = theme->parts.outlineEmptyPixel();
|
||||
auto pixelIcon = theme->parts.outlineFullPixel();
|
||||
|
||||
for (int i=0; i<9; ++i) {
|
||||
m_panel.outlineMatrix()
|
||||
->getItem(i)->setIcon(
|
||||
(matrix & (1 << (8-i))) ? pixelIcon: emptyIcon);
|
||||
}
|
||||
}
|
||||
|
||||
void onColorChange(const app::Color& color) {
|
||||
m_filter.color(color);
|
||||
restartPreview();
|
||||
@ -108,8 +134,24 @@ private:
|
||||
restartPreview();
|
||||
}
|
||||
|
||||
void onShapeChange(OutlineFilter::Shape shape) {
|
||||
m_filter.shape(shape);
|
||||
void onMatrixTypeChange() {
|
||||
OutlineFilter::Matrix matrix = 0;
|
||||
switch (m_panel.outlineType()->selectedItem()) {
|
||||
case CIRCLE: matrix = OutlineFilter::kCircleMatrix; break;
|
||||
case SQUARE: matrix = OutlineFilter::kSquareMatrix; break;
|
||||
case HORZ: matrix = OutlineFilter::kHorizontalMatrix; break;
|
||||
case VERT: matrix = OutlineFilter::kVerticalMatrix; break;
|
||||
}
|
||||
m_filter.matrix(matrix);
|
||||
updateButtonsFromMatrix();
|
||||
restartPreview();
|
||||
}
|
||||
|
||||
void onMatrixPixelChange(const int index) {
|
||||
OutlineFilter::Matrix matrix = m_filter.matrix();
|
||||
matrix ^= (1 << (8-index));
|
||||
m_filter.matrix(matrix);
|
||||
updateButtonsFromMatrix();
|
||||
restartPreview();
|
||||
}
|
||||
|
||||
@ -149,7 +191,7 @@ void OutlineCommand::onExecute(Context* context)
|
||||
|
||||
OutlineFilterWrapper filter(site.layer());
|
||||
filter.place((OutlineFilter::Place)get_config_int(ConfigSection, "Place", int(OutlineFilter::Place::Outside)));
|
||||
filter.shape((OutlineFilter::Shape)get_config_int(ConfigSection, "Shape", int(OutlineFilter::Shape::Circle)));
|
||||
filter.matrix((OutlineFilter::Matrix)get_config_int(ConfigSection, "Matrix", int(OutlineFilter::kCircleMatrix)));
|
||||
filter.color(get_config_color(ConfigSection, "Color", ColorBar::instance()->getFgColor()));
|
||||
filter.tiledMode(docPref.tiled.mode());
|
||||
filter.bgColor(app::Color::fromMask());
|
||||
@ -172,7 +214,7 @@ void OutlineCommand::onExecute(Context* context)
|
||||
OutlineWindow window(filter, filterMgr);
|
||||
if (window.doModal()) {
|
||||
set_config_int(ConfigSection, "Place", int(filter.place()));
|
||||
set_config_int(ConfigSection, "Shape", int(filter.shape()));
|
||||
set_config_int(ConfigSection, "Matrix", int(filter.matrix()));
|
||||
set_config_color(ConfigSection, "Color", filter.color());
|
||||
}
|
||||
}
|
||||
|
@ -25,12 +25,6 @@ using namespace doc;
|
||||
|
||||
namespace {
|
||||
|
||||
static const int kMatrices[int(OutlineFilter::Shape::NShapes)] =
|
||||
{ 0272, // Circle
|
||||
0777, // Square
|
||||
0070, // Horizontal
|
||||
0202 }; // Vertical
|
||||
|
||||
struct GetPixelsDelegate {
|
||||
color_t bgColor;
|
||||
int transparent; // Transparent pixels
|
||||
@ -38,9 +32,9 @@ namespace {
|
||||
int matrix;
|
||||
int bit;
|
||||
|
||||
void init(color_t bgColor, OutlineFilter::Shape shape) {
|
||||
void init(color_t bgColor, OutlineFilter::Matrix matrix) {
|
||||
this->bgColor = bgColor;
|
||||
this->matrix = kMatrices[int(shape)];
|
||||
this->matrix = matrix;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
@ -88,7 +82,7 @@ namespace {
|
||||
|
||||
OutlineFilter::OutlineFilter()
|
||||
: m_place(Place::Outside)
|
||||
, m_shape(Shape::Circle)
|
||||
, m_matrix(kCircleMatrix)
|
||||
, m_tiledMode(TiledMode::NONE)
|
||||
, m_color(0)
|
||||
, m_bgColor(0)
|
||||
@ -114,7 +108,7 @@ void OutlineFilter::applyToRgba(FilterManager* filterMgr)
|
||||
bool isTransparent;
|
||||
|
||||
GetPixelsDelegateRgba delegate;
|
||||
delegate.init(m_bgColor, m_shape);
|
||||
delegate.init(m_bgColor, m_matrix);
|
||||
|
||||
for (; x<x2; ++x, ++src_address, ++dst_address) {
|
||||
if (filterMgr->skipPixel())
|
||||
@ -155,7 +149,7 @@ void OutlineFilter::applyToGrayscale(FilterManager* filterMgr)
|
||||
bool isTransparent;
|
||||
|
||||
GetPixelsDelegateGrayscale delegate;
|
||||
delegate.init(m_bgColor, m_shape);
|
||||
delegate.init(m_bgColor, m_matrix);
|
||||
|
||||
for (; x<x2; ++x, ++src_address, ++dst_address) {
|
||||
if (filterMgr->skipPixel())
|
||||
@ -196,7 +190,7 @@ void OutlineFilter::applyToIndexed(FilterManager* filterMgr)
|
||||
bool isTransparent;
|
||||
|
||||
GetPixelsDelegateIndexed delegate(pal);
|
||||
delegate.init(m_bgColor, m_shape);
|
||||
delegate.init(m_bgColor, m_matrix);
|
||||
|
||||
for (; x<x2; ++x, ++src_address, ++dst_address) {
|
||||
if (filterMgr->skipPixel())
|
||||
|
@ -17,18 +17,23 @@ namespace filters {
|
||||
class OutlineFilter : public Filter {
|
||||
public:
|
||||
enum class Place { Outside, Inside };
|
||||
enum class Shape { Circle, Square, Horizontal, Vertical, NShapes };
|
||||
|
||||
typedef int Matrix;
|
||||
static const Matrix kCircleMatrix = 0252;
|
||||
static const Matrix kSquareMatrix = 0757;
|
||||
static const Matrix kHorizontalMatrix = 0050;
|
||||
static const Matrix kVerticalMatrix = 0202;
|
||||
|
||||
OutlineFilter();
|
||||
|
||||
void place(const Place place) { m_place = place; }
|
||||
void shape(const Shape shape) { m_shape = shape; }
|
||||
void matrix(const Matrix matrix) { m_matrix = matrix; }
|
||||
void tiledMode(const TiledMode tiledMode) { m_tiledMode = tiledMode; }
|
||||
void color(const doc::color_t color) { m_color = color; }
|
||||
void bgColor(const doc::color_t color) { m_bgColor = color; }
|
||||
|
||||
Place place() const { return m_place; }
|
||||
Shape shape() const { return m_shape; }
|
||||
Matrix matrix() const { return m_matrix; }
|
||||
TiledMode tiledMode() const { return m_tiledMode; }
|
||||
doc::color_t color() const { return m_color; }
|
||||
doc::color_t bgColor() const { return m_bgColor; }
|
||||
@ -41,7 +46,7 @@ namespace filters {
|
||||
|
||||
private:
|
||||
Place m_place;
|
||||
Shape m_shape;
|
||||
Matrix m_matrix;
|
||||
TiledMode m_tiledMode;
|
||||
doc::color_t m_color;
|
||||
doc::color_t m_bgColor;
|
||||
|
Loading…
x
Reference in New Issue
Block a user