2015-02-12 23:16:25 +08:00
|
|
|
// Aseprite
|
2021-03-03 00:50:49 +08:00
|
|
|
// Copyright (C) 2020-2021 Igara Studio S.A.
|
2018-03-16 23:26:38 +08:00
|
|
|
// 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.
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2012-01-06 06:45:03 +08:00
|
|
|
#include "config.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#endif
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2014-01-29 10:56:44 +08:00
|
|
|
#include "app/color.h"
|
|
|
|
|
#include "app/color_picker.h"
|
2015-07-03 05:13:47 +08:00
|
|
|
#include "app/commands/cmd_eyedropper.h"
|
2015-04-27 11:08:04 +08:00
|
|
|
#include "app/commands/commands.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/commands/params.h"
|
2020-06-26 06:47:58 +08:00
|
|
|
#include "app/context.h"
|
2015-05-13 22:46:49 +08:00
|
|
|
#include "app/pref/preferences.h"
|
2018-07-07 13:47:42 +08:00
|
|
|
#include "app/site.h"
|
2014-01-29 10:56:44 +08:00
|
|
|
#include "app/tools/tool_box.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/ui/color_bar.h"
|
|
|
|
|
#include "app/ui/editor/editor.h"
|
2014-01-29 10:56:44 +08:00
|
|
|
#include "ui/manager.h"
|
|
|
|
|
#include "ui/system.h"
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
namespace app {
|
2012-06-18 09:02:54 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
using namespace ui;
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2025-07-24 07:00:12 +08:00
|
|
|
EyedropperCommand::EyedropperCommand() : Command(CommandId::Eyedropper())
|
2012-01-06 06:45:03 +08:00
|
|
|
{
|
|
|
|
|
m_background = false;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-07 13:47:42 +08:00
|
|
|
void EyedropperCommand::pickSample(const Site& site,
|
2016-10-14 06:58:42 +08:00
|
|
|
const gfx::PointF& pixelPos,
|
|
|
|
|
const render::Projection& proj,
|
2020-08-22 05:07:37 +08:00
|
|
|
app::Color& color,
|
|
|
|
|
doc::tile_t& tile)
|
2015-07-03 05:13:47 +08:00
|
|
|
{
|
|
|
|
|
// Check if we've to grab alpha channel or the merged color.
|
|
|
|
|
Preferences& pref = Preferences::instance();
|
2016-10-14 08:19:25 +08:00
|
|
|
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;
|
|
|
|
|
}
|
2015-07-03 05:13:47 +08:00
|
|
|
|
|
|
|
|
ColorPicker picker;
|
2016-10-14 08:19:25 +08:00
|
|
|
picker.pickColor(site, pixelPos, proj, mode);
|
2015-07-03 05:13:47 +08:00
|
|
|
|
|
|
|
|
app::gen::EyedropperChannel channel = pref.eyedropper.channel();
|
|
|
|
|
|
2020-06-26 06:47:58 +08:00
|
|
|
if (site.tilemapMode() == TilemapMode::Tiles) {
|
2020-08-22 05:07:37 +08:00
|
|
|
tile = picker.tile();
|
2020-06-26 06:47:58 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-22 05:07:37 +08:00
|
|
|
app::Color picked = picker.color();
|
2015-07-03 05:13:47 +08:00
|
|
|
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:
|
2017-05-30 01:20:42 +08:00
|
|
|
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(),
|
2015-07-03 05:13:47 +08:00
|
|
|
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
|
2017-05-30 01:20:42 +08:00
|
|
|
color = app::Color::fromHsv(picked.getHsvHue(),
|
|
|
|
|
picked.getHsvSaturation(),
|
|
|
|
|
picked.getHsvValue(),
|
2015-07-03 05:13:47 +08:00
|
|
|
picked.getAlpha());
|
|
|
|
|
break;
|
|
|
|
|
case app::gen::EyedropperChannel::HSV:
|
|
|
|
|
if (picked.getAlpha() > 0)
|
2017-05-30 01:20:42 +08:00
|
|
|
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(),
|
2015-07-03 05:13:47 +08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-12 02:40:22 +08:00
|
|
|
void EyedropperCommand::onLoadParams(const Params& params)
|
2012-01-06 06:45:03 +08:00
|
|
|
{
|
2015-03-12 02:40:22 +08:00
|
|
|
std::string target = params.get("target");
|
2012-01-06 06:45:03 +08:00
|
|
|
if (target == "foreground")
|
|
|
|
|
m_background = false;
|
|
|
|
|
else if (target == "background")
|
|
|
|
|
m_background = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EyedropperCommand::onExecute(Context* context)
|
|
|
|
|
{
|
2018-03-16 23:26:38 +08:00
|
|
|
gfx::Point mousePos = ui::get_mouse_position();
|
2021-03-03 00:50:49 +08:00
|
|
|
Widget* widget = ui::Manager::getDefault()->pickFromScreenPos(mousePos);
|
2019-09-24 07:02:19 +08:00
|
|
|
if (!widget || widget->type() != Editor::Type())
|
2012-01-06 06:45:03 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Editor* editor = static_cast<Editor*>(widget);
|
2021-03-03 00:50:49 +08:00
|
|
|
executeOnMousePos(context,
|
|
|
|
|
editor,
|
|
|
|
|
editor->display()->nativeWindow()->pointFromScreen(mousePos),
|
|
|
|
|
!m_background);
|
2018-03-16 23:26:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EyedropperCommand::executeOnMousePos(Context* context,
|
|
|
|
|
Editor* editor,
|
|
|
|
|
const gfx::Point& mousePos,
|
|
|
|
|
const bool foreground)
|
|
|
|
|
{
|
|
|
|
|
ASSERT(editor);
|
|
|
|
|
|
2014-07-30 12:28:15 +08:00
|
|
|
Sprite* sprite = editor->sprite();
|
2012-01-06 06:45:03 +08:00
|
|
|
if (!sprite)
|
|
|
|
|
return;
|
|
|
|
|
|
2015-04-27 11:08:04 +08:00
|
|
|
// Discard current image brush
|
2017-11-23 21:06:13 +08:00
|
|
|
if (Preferences::instance().eyedropper.discardBrush()) {
|
2017-12-02 02:10:21 +08:00
|
|
|
Command* discardBrush = Commands::instance()->byId(CommandId::DiscardBrush());
|
2015-04-27 11:08:04 +08:00
|
|
|
context->executeCommand(discardBrush);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Pixel position to get
|
2018-03-16 23:26:38 +08:00
|
|
|
gfx::PointF pixelPos = editor->screenToEditorF(mousePos);
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2015-07-03 05:13:47 +08:00
|
|
|
// Start with fg/bg color
|
2017-10-04 02:17:48 +08:00
|
|
|
DisableColorBarEditMode disable;
|
2015-05-19 03:53:25 +08:00
|
|
|
Preferences& pref = Preferences::instance();
|
2020-08-22 05:07:37 +08:00
|
|
|
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();
|
2016-10-14 06:58:42 +08:00
|
|
|
pickSample(site, pixelPos, editor->projection(), color, tile);
|
2012-01-06 06:45:03 +08:00
|
|
|
|
2020-08-22 05:07:37 +08:00
|
|
|
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);
|
|
|
|
|
}
|
2012-01-06 06:45:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Command* CommandFactory::createEyedropperCommand()
|
|
|
|
|
{
|
|
|
|
|
return new EyedropperCommand;
|
|
|
|
|
}
|
2013-08-06 08:20:19 +08:00
|
|
|
|
|
|
|
|
} // namespace app
|