forked from aseprite/aseprite
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add widget to choose dithering algorithm + matrix
- Loading branch information
Showing
7 changed files
with
283 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
// Aseprite | ||
// Copyright (C) 2017 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/ui/dithering_selector.h" | ||
|
||
#include "app/modules/palettes.h" | ||
#include "app/ui/skin/skin_theme.h" | ||
#include "base/bind.h" | ||
#include "doc/conversion_she.h" | ||
#include "doc/image.h" | ||
#include "doc/image_ref.h" | ||
#include "doc/primitives.h" | ||
#include "render/quantization.h" | ||
#include "she/surface.h" | ||
#include "she/system.h" | ||
#include "ui/graphics.h" | ||
#include "ui/listitem.h" | ||
#include "ui/paint_event.h" | ||
#include "ui/size_hint_event.h" | ||
|
||
namespace app { | ||
|
||
using namespace ui; | ||
|
||
namespace { | ||
|
||
class DitherItem : public ListItem { | ||
public: | ||
DitherItem(render::DitheringAlgorithm algo, | ||
const render::DitheringMatrix& matrix, | ||
const std::string& text) | ||
: ListItem(text) | ||
, m_algo(algo) | ||
, m_matrix(matrix) { | ||
generatePreview(); | ||
} | ||
|
||
render::DitheringAlgorithm algo() const { return m_algo; } | ||
render::DitheringMatrix matrix() const { return m_matrix; } | ||
|
||
private: | ||
void generatePreview() { | ||
const doc::Palette* palette = get_current_palette(); | ||
|
||
const int w = 128, h = 16; | ||
doc::ImageRef image1(doc::Image::create(doc::IMAGE_RGB, w, h)); | ||
doc::clear_image(image1.get(), 0); | ||
for (int y=0; y<h; ++y) | ||
for (int x=0; x<w; ++x) { | ||
int v = 255 * x / (w-1); | ||
image1->putPixel(x, y, doc::rgba(v, v, v, 255)); | ||
} | ||
|
||
doc::ImageRef image2(doc::Image::create(doc::IMAGE_INDEXED, w, h)); | ||
doc::clear_image(image2.get(), 0); | ||
render::convert_pixel_format( | ||
image1.get(), image2.get(), IMAGE_INDEXED, | ||
m_algo, m_matrix, nullptr, palette, true, -1, nullptr); | ||
|
||
m_preview = she::instance()->createRgbaSurface(w, h); | ||
doc::convert_image_to_surface(image2.get(), palette, m_preview, | ||
0, 0, 0, 0, w, h); | ||
} | ||
|
||
void onSizeHint(SizeHintEvent& ev) override { | ||
gfx::Size sz = textSize(); | ||
|
||
sz.w = MAX(sz.w, m_preview->width()) + 4*guiscale(); | ||
sz.h += 6*guiscale() + m_preview->height(); | ||
|
||
ev.setSizeHint(sz); | ||
} | ||
|
||
void onPaint(PaintEvent& ev) override { | ||
Graphics* g = ev.graphics(); | ||
skin::SkinTheme* theme = static_cast<skin::SkinTheme*>(this->theme()); | ||
|
||
gfx::Color fg, bg; | ||
if (isSelected()) { | ||
fg = theme->colors.listitemSelectedText(); | ||
bg = theme->colors.listitemSelectedFace(); | ||
} | ||
else { | ||
fg = theme->colors.listitemNormalText(); | ||
bg = theme->colors.listitemNormalFace(); | ||
} | ||
|
||
gfx::Rect rc = clientBounds(); | ||
g->fillRect(bg, rc); | ||
|
||
gfx::Size textsz = textSize(); | ||
g->drawText(text(), fg, bg, | ||
gfx::Point(rc.x+2*guiscale(), | ||
rc.y+2*guiscale())); | ||
g->drawRgbaSurface( | ||
m_preview, | ||
rc.x+2*guiscale(), | ||
rc.y+4*guiscale()+textsz.h); | ||
} | ||
|
||
render::DitheringAlgorithm m_algo; | ||
render::DitheringMatrix m_matrix; | ||
she::Surface* m_preview; | ||
}; | ||
|
||
} // anonymous namespace | ||
|
||
DitheringSelector::DitheringSelector() | ||
{ | ||
addItem(new DitherItem(render::DitheringAlgorithm::None, | ||
render::DitheringMatrix(), "No Dithering")); | ||
addItem(new DitherItem(render::DitheringAlgorithm::Ordered, | ||
render::BayerMatrix(8), "Ordered Dithering - Bayer Matrix 8x8")); | ||
addItem(new DitherItem(render::DitheringAlgorithm::Ordered, | ||
render::BayerMatrix(4), "Ordered Dithering - Bayer Matrix 4x4")); | ||
addItem(new DitherItem(render::DitheringAlgorithm::Ordered, | ||
render::BayerMatrix(2), "Ordered Dithering - Bayer Matrix 2x2")); | ||
addItem(new DitherItem(render::DitheringAlgorithm::OldOrdered, | ||
render::BayerMatrix(8), "Old Dithering - Bayer Matrix 8x8")); | ||
addItem(new DitherItem(render::DitheringAlgorithm::OldOrdered, | ||
render::BayerMatrix(4), "Old Dithering - Bayer Matrix 4x4")); | ||
addItem(new DitherItem(render::DitheringAlgorithm::OldOrdered, | ||
render::BayerMatrix(2), "Old Dithering - Bayer Matrix 2x2")); | ||
|
||
setSelectedItemIndex(0); | ||
setMinSize(getItem(0)->sizeHint()); | ||
} | ||
|
||
render::DitheringAlgorithm DitheringSelector::ditheringAlgorithm() | ||
{ | ||
auto item = static_cast<DitherItem*>(getSelectedItem()); | ||
if (item) | ||
return item->algo(); | ||
else | ||
return render::DitheringAlgorithm::None; | ||
} | ||
|
||
render::DitheringMatrix DitheringSelector::ditheringMatrix() | ||
{ | ||
auto item = static_cast<DitherItem*>(getSelectedItem()); | ||
if (item) | ||
return item->matrix(); | ||
else | ||
return render::DitheringMatrix(); | ||
} | ||
|
||
} // namespace app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Aseprite | ||
// Copyright (C) 2017 David Capello | ||
// | ||
// This program is distributed under the terms of | ||
// the End-User License Agreement for Aseprite. | ||
|
||
#ifndef APP_UI_DITHERING_SELECTOR_H_INCLUDED | ||
#define APP_UI_DITHERING_SELECTOR_H_INCLUDED | ||
#pragma once | ||
|
||
#include "render/dithering_algorithm.h" | ||
#include "render/ordered_dither.h" | ||
#include "ui/box.h" | ||
#include "ui/combobox.h" | ||
|
||
namespace app { | ||
|
||
class DitheringSelector : public ui::ComboBox { | ||
public: | ||
DitheringSelector(); | ||
|
||
render::DitheringAlgorithm ditheringAlgorithm(); | ||
render::DitheringMatrix ditheringMatrix(); | ||
}; | ||
|
||
} // namespace app | ||
|
||
#endif |
Oops, something went wrong.