aseprite/src/app/commands/cmd_eyedropper.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

237 lines
7.9 KiB
C++
Raw Normal View History

2015-02-12 23:16:25 +08:00
// Aseprite
// Copyright (C) 2020-2021 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
2015-02-12 23:16:25 +08:00
//
2016-08-27 04:02:58 +08:00
// 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/color.h"
#include "app/color_picker.h"
#include "app/commands/cmd_eyedropper.h"
#include "app/commands/commands.h"
#include "app/commands/params.h"
#include "app/context.h"
#include "app/pref/preferences.h"
#include "app/site.h"
#include "app/tools/tool_box.h"
#include "app/ui/color_bar.h"
#include "app/ui/editor/editor.h"
#include "ui/manager.h"
#include "ui/system.h"
namespace app {
using namespace ui;
2025-07-24 07:00:12 +08:00
EyedropperCommand::EyedropperCommand() : Command(CommandId::Eyedropper())
{
m_background = false;
}
void EyedropperCommand::pickSample(const Site& site,
const gfx::PointF& pixelPos,
const render::Projection& proj,
app::Color& color,
doc::tile_t& tile)
{
// Check if we've to grab alpha channel or the merged color.
Preferences& pref = Preferences::instance();
ColorPicker::Mode mode = ColorPicker::FromComposition;
switch (pref.eyedropper.sample()) {
case app::gen::EyedropperSample::ALL_LAYERS: mode = ColorPicker::FromComposition; break;
case app::gen::EyedropperSample::CURRENT_LAYER: mode = ColorPicker::FromActiveLayer; break;
case app::gen::EyedropperSample::FIRST_REFERENCE_LAYER:
mode = ColorPicker::FromFirstReferenceLayer;
break;
}
ColorPicker picker;
picker.pickColor(site, pixelPos, proj, mode);
app::gen::EyedropperChannel channel = pref.eyedropper.channel();
if (site.tilemapMode() == TilemapMode::Tiles) {
tile = picker.tile();
return;
}
app::Color picked = picker.color();
switch (channel) {
case app::gen::EyedropperChannel::COLOR_ALPHA: color = picked; break;
case app::gen::EyedropperChannel::COLOR:
if (picked.getAlpha() > 0)
color = app::Color::fromRgb(picked.getRed(),
picked.getGreen(),
picked.getBlue(),
color.getAlpha());
break;
case app::gen::EyedropperChannel::ALPHA:
switch (color.getType()) {
case app::Color::RgbType:
case app::Color::IndexType:
color = app::Color::fromRgb(color.getRed(),
color.getGreen(),
color.getBlue(),
picked.getAlpha());
break;
case app::Color::HsvType:
color = app::Color::fromHsv(color.getHsvHue(),
color.getHsvSaturation(),
color.getHsvValue(),
picked.getAlpha());
break;
case app::Color::HslType:
color = app::Color::fromHsl(color.getHslHue(),
color.getHslSaturation(),
color.getHslLightness(),
picked.getAlpha());
break;
case app::Color::GrayType:
color = app::Color::fromGray(color.getGray(), picked.getAlpha());
break;
}
break;
case app::gen::EyedropperChannel::RGBA:
if (picked.getType() == app::Color::RgbType)
color = picked;
else
color = app::Color::fromRgb(picked.getRed(),
picked.getGreen(),
picked.getBlue(),
picked.getAlpha());
break;
case app::gen::EyedropperChannel::RGB:
if (picked.getAlpha() > 0)
color = app::Color::fromRgb(picked.getRed(),
picked.getGreen(),
picked.getBlue(),
color.getAlpha());
break;
case app::gen::EyedropperChannel::HSVA:
if (picked.getType() == app::Color::HsvType)
color = picked;
else
color = app::Color::fromHsv(picked.getHsvHue(),
picked.getHsvSaturation(),
picked.getHsvValue(),
picked.getAlpha());
break;
case app::gen::EyedropperChannel::HSV:
if (picked.getAlpha() > 0)
color = app::Color::fromHsv(picked.getHsvHue(),
picked.getHsvSaturation(),
picked.getHsvValue(),
color.getAlpha());
break;
case app::gen::EyedropperChannel::HSLA:
if (picked.getType() == app::Color::HslType)
color = picked;
else
color = app::Color::fromHsl(picked.getHslHue(),
picked.getHslSaturation(),
picked.getHslLightness(),
picked.getAlpha());
break;
case app::gen::EyedropperChannel::HSL:
if (picked.getAlpha() > 0)
color = app::Color::fromHsl(picked.getHslHue(),
picked.getHslSaturation(),
picked.getHslLightness(),
color.getAlpha());
break;
case app::gen::EyedropperChannel::GRAYA:
if (picked.getType() == app::Color::GrayType)
color = picked;
else
color = app::Color::fromGray(picked.getGray(), picked.getAlpha());
break;
case app::gen::EyedropperChannel::GRAY:
if (picked.getAlpha() > 0)
color = app::Color::fromGray(picked.getGray(), color.getAlpha());
break;
case app::gen::EyedropperChannel::INDEX:
color = app::Color::fromIndex(picked.getIndex());
break;
}
}
void EyedropperCommand::onLoadParams(const Params& params)
{
std::string target = params.get("target");
if (target == "foreground")
m_background = false;
else if (target == "background")
m_background = true;
}
void EyedropperCommand::onExecute(Context* context)
{
gfx::Point mousePos = ui::get_mouse_position();
Widget* widget = ui::Manager::getDefault()->pickFromScreenPos(mousePos);
2019-09-24 07:02:19 +08:00
if (!widget || widget->type() != Editor::Type())
return;
Editor* editor = static_cast<Editor*>(widget);
executeOnMousePos(context,
editor,
editor->display()->nativeWindow()->pointFromScreen(mousePos),
!m_background);
}
void EyedropperCommand::executeOnMousePos(Context* context,
Editor* editor,
const gfx::Point& mousePos,
const bool foreground)
{
ASSERT(editor);
Sprite* sprite = editor->sprite();
if (!sprite)
return;
// Discard current image brush
if (Preferences::instance().eyedropper.discardBrush()) {
Command* discardBrush = Commands::instance()->byId(CommandId::DiscardBrush());
context->executeCommand(discardBrush);
}
// Pixel position to get
gfx::PointF pixelPos = editor->screenToEditorF(mousePos);
// Start with fg/bg color
DisableColorBarEditMode disable;
Preferences& pref = Preferences::instance();
app::Color color = (foreground ? pref.colorBar.fgColor() : pref.colorBar.bgColor());
doc::tile_t tile = (foreground ? pref.colorBar.fgTile() : pref.colorBar.bgTile());
Site site = editor->getSite();
pickSample(site, pixelPos, editor->projection(), color, tile);
if (site.tilemapMode() == TilemapMode::Tiles) {
if (foreground)
pref.colorBar.fgTile(tile);
else
pref.colorBar.bgTile(tile);
}
else {
if (foreground)
pref.colorBar.fgColor(color);
else
pref.colorBar.bgColor(color);
}
}
Command* CommandFactory::createEyedropperCommand()
{
return new EyedropperCommand;
}
} // namespace app