Adjust default ink to be more pixel-art friendly (just replace RGBA values)

Now that we have alpha channel in color selector and palette entries, it's
nice to have as a default ink a more pixel-art friendly, i.e.
an ink that just replace RGBA values instead of doing alpha compositing.

Issue #286
This commit is contained in:
David Capello 2015-07-02 13:16:06 -03:00
parent e9308c2d35
commit d80b984f00
9 changed files with 99 additions and 104 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -372,6 +372,9 @@
<part id="canvas_s" x="112" y="128" w="16" h="16" />
<part id="canvas_se" x="128" y="128" w="16" h="16" />
<part id="canvas_empty" x="96" y="96" w="1" h="1" />
<part id="ink_default" x="144" y="144" w="16" h="16" />
<part id="ink_composite" x="160" y="144" w="16" h="16" />
<part id="ink_lock_alpha" x="176" y="144" w="16" h="16" />
</parts>
<stylesheet>

View File

@ -14,7 +14,8 @@ namespace tools {
enum class InkType {
DEFAULT = 0,
SET_ALPHA = 1,
REPLACE_PIXEL = 0,
ALPHA_COMPOSITING = 1,
LOCK_ALPHA = 2,
};

View File

@ -62,11 +62,7 @@ public:
case Opaque: m_proc = ink_processing[INK_OPAQUE][depth]; break;
case SetAlpha: m_proc = ink_processing[INK_SETALPHA][depth]; break;
case LockAlpha: m_proc = ink_processing[INK_LOCKALPHA][depth]; break;
default:
m_proc = (loop->getOpacity() == 255 ?
ink_processing[INK_OPAQUE][depth]:
ink_processing[INK_TRANSPARENT][depth]);
break;
default: m_proc = ink_processing[INK_TRANSPARENT][depth]; break;
}
}
}

View File

@ -42,6 +42,7 @@
#include "ui/int_entry.h"
#include "ui/label.h"
#include "ui/listitem.h"
#include "ui/menu.h"
#include "ui/popup_window.h"
#include "ui/preferred_size_event.h"
#include "ui/theme.h"
@ -147,6 +148,7 @@ private:
void closePopup() {
m_popupWindow.closeWindow(NULL);
deselectItems();
}
void onBrushChange(const BrushRef& brush) {
@ -319,66 +321,67 @@ protected:
}
};
class ContextBar::InkTypeField : public ComboBox
class ContextBar::InkTypeField : public ButtonSet
{
public:
InkTypeField() : m_lock(false) {
// The same order as in InkType
addItem("Default Ink");
#if 0
addItem("Opaque");
#endif
addItem("Set Alpha");
addItem("Lock Alpha");
#if 0
addItem("Merge");
addItem("Shading");
addItem("Replace");
addItem("Erase");
addItem("Selection");
addItem("Blur");
addItem("Jumble");
#endif
InkTypeField(ContextBar* owner) : ButtonSet(1)
, m_owner(owner) {
addItem(
static_cast<SkinTheme*>(getTheme())->get_part(PART_INK_DEFAULT));
}
void setInkType(InkType inkType) {
int index = 0;
int part = PART_INK_DEFAULT;
switch (inkType) {
case InkType::DEFAULT: index = 0; break;
case InkType::SET_ALPHA: index = 1; break;
case InkType::LOCK_ALPHA: index = 2; break;
case InkType::REPLACE_PIXEL: part = PART_INK_DEFAULT; break;
case InkType::ALPHA_COMPOSITING: part = PART_INK_COMPOSITE; break;
case InkType::LOCK_ALPHA: part = PART_INK_LOCK_ALPHA; break;
}
m_lock = true;
setSelectedItemIndex(index);
m_lock = false;
getItem(0)->setIcon(
static_cast<SkinTheme*>(getTheme())->get_part(part));
}
protected:
void onChange() override {
ComboBox::onChange();
void onItemChange() override {
ButtonSet::onItemChange();
if (m_lock)
return;
gfx::Rect bounds = getBounds();
InkType inkType = InkType::DEFAULT;
switch (getSelectedItemIndex()) {
case 0: inkType = InkType::DEFAULT; break;
case 1: inkType = InkType::SET_ALPHA; break;
case 2: inkType = InkType::LOCK_ALPHA; break;
}
Menu menu;
MenuItem
replace("Replace Pixel"),
alphacompo("Alpha Compositing"),
lockalpha("Lock Alpha");
menu.addChild(&replace);
menu.addChild(&alphacompo);
menu.addChild(&lockalpha);
Tool* tool = App::instance()->activeTool();
switch (Preferences::instance().tool(tool).ink()) {
case tools::InkType::REPLACE_PIXEL: replace.setSelected(true); break;
case tools::InkType::ALPHA_COMPOSITING: alphacompo.setSelected(true); break;
case tools::InkType::LOCK_ALPHA: lockalpha.setSelected(true); break;
}
replace.Click.connect(Bind<void>(&InkTypeField::selectInk, this, InkType::REPLACE_PIXEL));
alphacompo.Click.connect(Bind<void>(&InkTypeField::selectInk, this, InkType::ALPHA_COMPOSITING));
lockalpha.Click.connect(Bind<void>(&InkTypeField::selectInk, this, InkType::LOCK_ALPHA));
menu.showPopup(gfx::Point(bounds.x, bounds.y+bounds.h));
deselectItems();
}
void selectInk(InkType inkType) {
Tool* tool = App::instance()->activeTool();
Preferences::instance().tool(tool).ink(inkType);
m_owner->updateForCurrentTool();
}
void onCloseListBox() override {
releaseFocus();
}
bool m_lock;
ContextBar* m_owner;
};
class ContextBar::InkOpacityField : public IntEntry
@ -802,9 +805,9 @@ ContextBar::ContextBar()
addChild(m_contiguous = new ContiguousField());
addChild(m_stopAtGrid = new StopAtGridField());
addChild(m_inkType = new InkTypeField());
addChild(m_inkType = new InkTypeField(this));
addChild(m_opacityLabel = new Label("Opacity:"));
addChild(m_inkOpacityLabel = new Label("Opacity:"));
addChild(m_inkOpacity = new InkOpacityField());
addChild(m_grabAlpha = new GrabAlphaField());
@ -832,7 +835,7 @@ ContextBar::ContextBar()
m_freehandBox->addChild(m_freehandAlgo = new FreehandAlgorithmField());
setup_mini_font(m_toleranceLabel);
setup_mini_font(m_opacityLabel);
setup_mini_font(m_inkOpacityLabel);
TooltipManager* tooltipManager = new TooltipManager();
addChild(tooltipManager);
@ -840,7 +843,8 @@ ContextBar::ContextBar()
tooltipManager->addTooltipFor(m_brushType, "Brush Type", BOTTOM);
tooltipManager->addTooltipFor(m_brushSize, "Brush Size (in pixels)", BOTTOM);
tooltipManager->addTooltipFor(m_brushAngle, "Brush Angle (in degrees)", BOTTOM);
tooltipManager->addTooltipFor(m_inkOpacity, "Opacity (Alpha value in RGBA)", BOTTOM);
tooltipManager->addTooltipFor(m_inkType, "Ink", BOTTOM);
tooltipManager->addTooltipFor(m_inkOpacity, "Opacity (paint intensity)", BOTTOM);
tooltipManager->addTooltipFor(m_sprayWidth, "Spray Width", BOTTOM);
tooltipManager->addTooltipFor(m_spraySpeed, "Spray Speed", BOTTOM);
tooltipManager->addTooltipFor(m_transparentColor, "Transparent Color", BOTTOM);
@ -939,6 +943,25 @@ void ContextBar::updateForTool(tools::Tool* tool)
m_brushPatternField->setBrushPattern(
preferences.brush.pattern());
// Tool ink
bool isPaint = tool &&
(tool->getInk(0)->isPaint() ||
tool->getInk(1)->isPaint());
bool isEffect = tool &&
(tool->getInk(0)->isEffect() ||
tool->getInk(1)->isEffect());
// True if the current tool support opacity slider
bool supportOpacity = (isPaint || isEffect);
// True if it makes sense to change the ink property for the current
// tool.
bool hasInk = tool &&
((tool->getInk(0)->isPaint() && !tool->getInk(0)->isEffect()) ||
(tool->getInk(1)->isPaint() && !tool->getInk(1)->isEffect()));
bool hasInkWithOpacity = false;
if (toolPref) {
m_tolerance->setTextf("%d", toolPref->tolerance());
m_contiguous->setSelected(toolPref->contiguous());
@ -948,6 +971,10 @@ void ContextBar::updateForTool(tools::Tool* tool)
m_inkType->setInkType(toolPref->ink());
m_inkOpacity->setTextf("%d", toolPref->opacity());
hasInkWithOpacity =
((isPaint && toolPref->ink() != tools::InkType::REPLACE_PIXEL) ||
(isEffect));
m_freehandAlgo->setFreehandAlgorithm(toolPref->freehandAlgorithm());
m_sprayWidth->setValue(toolPref->spray.width());
@ -957,13 +984,6 @@ void ContextBar::updateForTool(tools::Tool* tool)
m_grabAlpha->setSelected(preferences.editor.grabAlpha());
m_autoSelectLayer->setSelected(preferences.editor.autoSelectLayer());
// True if the current tool needs opacity options
bool hasOpacity = tool &&
(tool->getInk(0)->isPaint() ||
tool->getInk(0)->isEffect() ||
tool->getInk(1)->isPaint() ||
tool->getInk(1)->isEffect());
// True if we have an image as brush
bool hasImageBrush = (activeBrush()->type() == kImageBrushType);
@ -977,10 +997,6 @@ void ContextBar::updateForTool(tools::Tool* tool)
(tool->getInk(0)->isCelMovement() ||
tool->getInk(1)->isCelMovement());
// True if it makes sense to change the ink property for the current
// tool.
bool hasInk = hasOpacity;
// True if the current tool is floodfill
bool isFloodfill = tool &&
(tool->getPointShape(0)->isFloodFill() ||
@ -1005,16 +1021,16 @@ void ContextBar::updateForTool(tools::Tool* tool)
tool->getController(1)->isFreehand());
// Show/Hide fields
m_brushType->setVisible(hasOpacity && (!isFloodfill || (isFloodfill && hasImageBrush)));
m_brushSize->setVisible(hasOpacity && !isFloodfill && !hasImageBrush);
m_brushAngle->setVisible(hasOpacity && !isFloodfill && !hasImageBrush);
m_brushPatternField->setVisible(hasOpacity && hasImageBrush);
m_opacityLabel->setVisible(hasOpacity);
m_brushType->setVisible(supportOpacity && (!isFloodfill || (isFloodfill && hasImageBrush)));
m_brushSize->setVisible(supportOpacity && !isFloodfill && !hasImageBrush);
m_brushAngle->setVisible(supportOpacity && !isFloodfill && !hasImageBrush);
m_brushPatternField->setVisible(supportOpacity && hasImageBrush);
m_inkType->setVisible(hasInk && !hasImageBrush);
m_inkOpacity->setVisible(hasOpacity);
m_inkOpacityLabel->setVisible(hasInkWithOpacity && supportOpacity);
m_inkOpacity->setVisible(hasInkWithOpacity && supportOpacity);
m_grabAlpha->setVisible(isEyedropper);
m_autoSelectLayer->setVisible(isMove);
m_freehandBox->setVisible(isFreehand && hasOpacity);
m_freehandBox->setVisible(isFreehand && supportOpacity);
m_toleranceLabel->setVisible(hasTolerance);
m_tolerance->setVisible(hasTolerance);
m_contiguous->setVisible(hasTolerance);

View File

@ -118,7 +118,7 @@ namespace app {
ContiguousField* m_contiguous;
StopAtGridField* m_stopAtGrid;
InkTypeField* m_inkType;
ui::Label* m_opacityLabel;
ui::Label* m_inkOpacityLabel;
InkOpacityField* m_inkOpacity;
GrabAlphaField* m_grabAlpha;
AutoSelectLayerField* m_autoSelectLayer;

View File

@ -916,49 +916,21 @@ tools::Ink* Editor::getCurrentEditorInk()
break;
}
}
else {
// Only paint tools can have different inks
else if (ink->isPaint() && !ink->isEffect()) {
tools::InkType inkType = Preferences::instance().tool(tool).ink();
const char* id = NULL;
switch (inkType) {
case tools::InkType::DEFAULT:
// Do nothing
case tools::InkType::REPLACE_PIXEL:
id = tools::WellKnownInks::PaintOpaque;
break;
case tools::InkType::SET_ALPHA:
id = tools::WellKnownInks::PaintSetAlpha;
case tools::InkType::ALPHA_COMPOSITING:
id = tools::WellKnownInks::Paint;
break;
case tools::InkType::LOCK_ALPHA:
id = tools::WellKnownInks::PaintLockAlpha;
break;
#if 0
case tools::InkType::OPAQUE:
id = tools::WellKnownInks::PaintOpaque;
break;
case tools::InkType::MERGE:
id = tools::WellKnownInks::Paint;
break;
case tools::InkType::SHADING:
id = tools::WellKnownInks::Shading;
break;
case tools::InkType::REPLACE:
if (!m_secondaryButton)
id = tools::WellKnownInks::ReplaceBgWithFg;
else
id = tools::WellKnownInks::ReplaceFgWithBg;
break;
case tools::InkType::ERASER:
id = tools::WellKnownInks::Eraser;
break;
case tools::InkType::SELECTION:
id = tools::WellKnownInks::Selection;
break;
case tools::InkType::BLUR:
id = tools::WellKnownInks::Blur;
break;
case tools::InkType::JUMBLE:
id = tools::WellKnownInks::Jumble;
break;
#endif
}
if (id)

View File

@ -176,6 +176,10 @@ namespace app {
PART_FREEHAND_ALGO_DOTS,
PART_FREEHAND_ALGO_DOTS_SELECTED,
PART_INK_DEFAULT,
PART_INK_COMPOSITE,
PART_INK_LOCK_ALPHA,
PARTS
};

View File

@ -278,6 +278,9 @@ SkinTheme::SkinTheme()
sheet_mapping["freehand_algo_pixel_perfect_selected"] = PART_FREEHAND_ALGO_PIXEL_PERFECT_SELECTED;
sheet_mapping["freehand_algo_dots"] = PART_FREEHAND_ALGO_DOTS;
sheet_mapping["freehand_algo_dots_selected"] = PART_FREEHAND_ALGO_DOTS_SELECTED;
sheet_mapping["ink_default"] = PART_INK_DEFAULT;
sheet_mapping["ink_composite"] = PART_INK_COMPOSITE;
sheet_mapping["ink_lock_alpha"] = PART_INK_LOCK_ALPHA;
}
SkinTheme::~SkinTheme()