Add possibility to select any matrix to run the OutlineFilter

This commit is contained in:
David Capello 2019-04-16 17:54:42 -03:00
parent be74710067
commit 8551fbda26
6 changed files with 96 additions and 32 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -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" />

View File

@ -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" />

View File

@ -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());
}
}

View File

@ -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())

View File

@ -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;