Add "ink" parameter to app.useTool() + minor needed refactors

This commit is contained in:
David Capello 2020-05-20 16:34:43 -03:00
parent d71404aa6c
commit 1ec502d242
9 changed files with 136 additions and 70 deletions

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2020 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello // Copyright (C) 2001-2017 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -11,7 +12,7 @@
#include "app/app.h" #include "app/app.h"
#include "app/commands/command.h" #include "app/commands/command.h"
#include "app/commands/commands.h" #include "app/commands/commands.h"
#include "app/commands/params.h" #include "app/commands/new_params.h"
#include "app/i18n/strings.h" #include "app/i18n/strings.h"
#include "app/tools/ink_type.h" #include "app/tools/ink_type.h"
#include "app/ui/context_bar.h" #include "app/ui/context_bar.h"
@ -19,60 +20,42 @@
namespace app { namespace app {
class SetInkTypeCommand : public Command { struct SetInkTypeParams : public NewParams {
Param<app::tools::InkType> type { this, app::tools::InkType::DEFAULT, "type" };
};
class SetInkTypeCommand : public CommandWithNewParams<SetInkTypeParams> {
public: public:
SetInkTypeCommand(); SetInkTypeCommand();
protected: protected:
bool onNeedsParams() const override { return true; } bool onNeedsParams() const override { return true; }
void onLoadParams(const Params& params) override;
bool onChecked(Context* context) override; bool onChecked(Context* context) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
std::string onGetFriendlyName() const override; std::string onGetFriendlyName() const override;
private:
tools::InkType m_type;
}; };
SetInkTypeCommand::SetInkTypeCommand() SetInkTypeCommand::SetInkTypeCommand()
: Command(CommandId::SetInkType(), CmdUIOnlyFlag) : CommandWithNewParams(CommandId::SetInkType(), CmdUIOnlyFlag)
, m_type(tools::InkType::DEFAULT)
{ {
} }
void SetInkTypeCommand::onLoadParams(const Params& params)
{
std::string typeStr = params.get("type");
if (typeStr == "simple")
m_type = tools::InkType::SIMPLE;
else if (typeStr == "alpha-compositing")
m_type = tools::InkType::ALPHA_COMPOSITING;
else if (typeStr == "copy-color")
m_type = tools::InkType::COPY_COLOR;
else if (typeStr == "lock-alpha")
m_type = tools::InkType::LOCK_ALPHA;
else if (typeStr == "shading")
m_type = tools::InkType::SHADING;
else
m_type = tools::InkType::DEFAULT;
}
bool SetInkTypeCommand::onChecked(Context* context) bool SetInkTypeCommand::onChecked(Context* context)
{ {
tools::Tool* tool = App::instance()->activeTool(); tools::Tool* tool = App::instance()->activeTool();
return (Preferences::instance().tool(tool).ink() == m_type); return (Preferences::instance().tool(tool).ink() == params().type());
} }
void SetInkTypeCommand::onExecute(Context* context) void SetInkTypeCommand::onExecute(Context* context)
{ {
if (App::instance()->contextBar() != nullptr) if (App::instance()->contextBar() != nullptr)
App::instance()->contextBar()->setInkType(m_type); App::instance()->contextBar()->setInkType(params().type());
} }
std::string SetInkTypeCommand::onGetFriendlyName() const std::string SetInkTypeCommand::onGetFriendlyName() const
{ {
std::string ink; std::string ink;
switch (m_type) { switch (params().type()) {
case tools::InkType::SIMPLE: case tools::InkType::SIMPLE:
ink = Strings::inks_simple_ink(); ink = Strings::inks_simple_ink();
break; break;

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2019 Igara Studio S.A. // Copyright (C) 2019-2020 Igara Studio S.A.
// //
// This program is distributed under the terms of // This program is distributed under the terms of
// the End-User License Agreement for Aseprite. // the End-User License Agreement for Aseprite.
@ -13,6 +13,7 @@
#include "app/color.h" #include "app/color.h"
#include "app/doc_exporter.h" #include "app/doc_exporter.h"
#include "app/sprite_sheet_type.h" #include "app/sprite_sheet_type.h"
#include "app/tools/ink_type.h"
#include "base/convert_to.h" #include "base/convert_to.h"
#include "base/split_string.h" #include "base/split_string.h"
#include "base/string.h" #include "base/string.h"
@ -26,6 +27,7 @@
#ifdef ENABLE_SCRIPTING #ifdef ENABLE_SCRIPTING
#include "app/script/engine.h" #include "app/script/engine.h"
#include "app/script/luacpp.h" #include "app/script/luacpp.h"
#include "app/script/values.h"
#endif #endif
namespace app { namespace app {
@ -184,6 +186,12 @@ void Param<filters::ColorCurve>::fromString(const std::string& value)
setValue(curve); setValue(curve);
} }
template<>
void Param<tools::InkType>::fromString(const std::string& value)
{
setValue(tools::string_id_to_ink_type(value));
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Convert values from Lua // Convert values from Lua
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@ -312,6 +320,12 @@ void Param<filters::ColorCurve>::fromLua(lua_State* L, int index)
} }
} }
template<>
void Param<tools::InkType>::fromLua(lua_State* L, int index)
{
script::get_value_from_lua<tools::InkType>(L, index);
}
void CommandWithNewParamsBase::loadParamsFromLuaTable(lua_State* L, int index) void CommandWithNewParamsBase::loadParamsFromLuaTable(lua_State* L, int index)
{ {
onResetValues(); onResetValues();

View File

@ -282,9 +282,21 @@ int App_useTool(lua_State* L)
// Options to create the ToolLoop (tool, ink, color, opacity, etc.) // Options to create the ToolLoop (tool, ink, color, opacity, etc.)
ToolLoopParams params; ToolLoopParams params;
// Mouse button
params.button = tools::ToolLoop::Left;
type = lua_getfield(L, 1, "button");
if (type != LUA_TNIL) {
// Only supported button at the moment left (default) or right
if (lua_tointeger(L, -1) == (int)ui::kButtonRight)
params.button = tools::ToolLoop::Right;
}
lua_pop(L, 1);
// Select tool by name // Select tool by name
params.tool = App::instance()->activeToolManager()->activeTool(); auto activeToolMgr = App::instance()->activeToolManager();
params.ink = params.tool->getInk(0); params.tool = activeToolMgr->activeTool();
params.ink = params.tool->getInk(params.button == tools::ToolLoop::Left ? 0: 1);
params.controller = params.tool->getController(params.button);
type = lua_getfield(L, 1, "tool"); type = lua_getfield(L, 1, "tool");
if (type != LUA_TNIL) { if (type != LUA_TNIL) {
if (auto toolArg = get_tool_from_arg(L, -1)) { if (auto toolArg = get_tool_from_arg(L, -1)) {
@ -296,18 +308,12 @@ int App_useTool(lua_State* L)
} }
lua_pop(L, 1); lua_pop(L, 1);
// Mouse button // Select ink by name
params.button = tools::ToolLoop::Left; type = lua_getfield(L, 1, "ink");
type = lua_getfield(L, 1, "button"); if (type != LUA_TNIL)
if (type != LUA_TNIL) { params.inkType = get_value_from_lua<tools::InkType>(L, -1);
// Only supported button at the moment left (default) or right
if (lua_tointeger(L, -1) == (int)ui::kButtonRight)
params.button = tools::ToolLoop::Right;
}
lua_pop(L, 1); lua_pop(L, 1);
params.controller = params.tool->getController(params.button);
// Color // Color
type = lua_getfield(L, 1, "color"); type = lua_getfield(L, 1, "color");
if (type != LUA_TNIL) if (type != LUA_TNIL)
@ -325,6 +331,13 @@ int App_useTool(lua_State* L)
params.bg = params.fg; params.bg = params.fg;
lua_pop(L, 1); lua_pop(L, 1);
// Adjust ink depending on "inkType" and "color"
// (e.g. InkType::SIMPLE depends on the color too, to adjust
// eraser/alpha compositing/opaque depending on the color alpha
// value).
params.ink = activeToolMgr->adjustToolInkDependingOnSelectedInkType(
params.ink, params.inkType, params.fg);
// Brush // Brush
type = lua_getfield(L, 1, "brush"); type = lua_getfield(L, 1, "brush");
if (type != LUA_TNIL) if (type != LUA_TNIL)

View File

@ -329,6 +329,16 @@ Engine::Engine()
setfield_integer(L, "NONE", doc::BrushPattern::PAINT_BRUSH); setfield_integer(L, "NONE", doc::BrushPattern::PAINT_BRUSH);
lua_pop(L, 1); lua_pop(L, 1);
lua_newtable(L);
lua_pushvalue(L, -1);
lua_setglobal(L, "Ink");
setfield_integer(L, "SIMPLE", app::tools::InkType::SIMPLE);
setfield_integer(L, "ALPHA_COMPOSITING", app::tools::InkType::ALPHA_COMPOSITING);
setfield_integer(L, "COPY_COLOR", app::tools::InkType::COPY_COLOR);
setfield_integer(L, "LOCK_ALPHA", app::tools::InkType::LOCK_ALPHA);
setfield_integer(L, "SHADING", app::tools::InkType::SHADING);
lua_pop(L, 1);
lua_newtable(L); lua_newtable(L);
lua_pushvalue(L, -1); lua_pushvalue(L, -1);
lua_setglobal(L, "FilterChannels"); lua_setglobal(L, "FilterChannels");

View File

@ -48,14 +48,14 @@ namespace doc {
class WithUserData; class WithUserData;
} }
namespace tools {
class Tool;
}
namespace app { namespace app {
class Site; class Site;
namespace tools {
class Tool;
}
namespace script { namespace script {
enum class FileAccessMode { enum class FileAccessMode {
@ -146,7 +146,7 @@ namespace app {
void push_sprite_slices(lua_State* L, doc::Sprite* sprite); void push_sprite_slices(lua_State* L, doc::Sprite* sprite);
void push_sprite_tags(lua_State* L, doc::Sprite* sprite); void push_sprite_tags(lua_State* L, doc::Sprite* sprite);
void push_sprites(lua_State* L); void push_sprites(lua_State* L);
void push_tool(lua_State* L, tools::Tool* tool); void push_tool(lua_State* L, app::tools::Tool* tool);
void push_userdata(lua_State* L, doc::WithUserData* userData); void push_userdata(lua_State* L, doc::WithUserData* userData);
void push_version(lua_State* L, const base::Version& ver); void push_version(lua_State* L, const base::Version& ver);
@ -162,7 +162,7 @@ namespace app {
doc::Cel* get_image_cel_from_arg(lua_State* L, int index); doc::Cel* get_image_cel_from_arg(lua_State* L, int index);
doc::frame_t get_frame_number_from_arg(lua_State* L, int index); doc::frame_t get_frame_number_from_arg(lua_State* L, int index);
const doc::Mask* get_mask_from_arg(lua_State* L, int index); const doc::Mask* get_mask_from_arg(lua_State* L, int index);
tools::Tool* get_tool_from_arg(lua_State* L, int index); app::tools::Tool* get_tool_from_arg(lua_State* L, int index);
doc::BrushRef get_brush_from_arg(lua_State* L, int index); doc::BrushRef get_brush_from_arg(lua_State* L, int index);
// Used by App.open(), Sprite{ fromFile }, and Image{ fromFile } // Used by App.open(), Sprite{ fromFile }, and Image{ fromFile }

View File

@ -126,6 +126,23 @@ gfx::Rect get_value_from_lua(lua_State* L, int index) {
return convert_args_into_rect(L, index); return convert_args_into_rect(L, index);
} }
// ----------------------------------------------------------------------
// tools::InkType
template<>
void push_value_to_lua(lua_State* L, const app::tools::InkType& inkType) {
lua_pushinteger(L, (int)inkType);
}
template<>
app::tools::InkType get_value_from_lua(lua_State* L, int index) {
if (lua_type(L, index) == LUA_TSTRING) {
if (const char* s = lua_tostring(L, index))
return app::tools::string_id_to_ink_type(s);
}
return (app::tools::InkType)lua_tointeger(L, index);
}
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// enums // enums
@ -163,7 +180,6 @@ FOR_ENUM(app::gen::TimelinePosition)
FOR_ENUM(app::gen::WindowColorProfile) FOR_ENUM(app::gen::WindowColorProfile)
FOR_ENUM(app::gen::ToGrayAlgorithm) FOR_ENUM(app::gen::ToGrayAlgorithm)
FOR_ENUM(app::tools::FreehandAlgorithm) FOR_ENUM(app::tools::FreehandAlgorithm)
FOR_ENUM(app::tools::InkType)
FOR_ENUM(app::tools::RotationAlgorithm) FOR_ENUM(app::tools::RotationAlgorithm)
FOR_ENUM(doc::AniDir) FOR_ENUM(doc::AniDir)
FOR_ENUM(doc::BrushPattern) FOR_ENUM(doc::BrushPattern)

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018 Igara Studio S.A. // Copyright (C) 2018-2020 Igara Studio S.A.
// Copyright (C) 2016 David Capello // Copyright (C) 2016 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -11,6 +11,7 @@
#include "app/tools/active_tool.h" #include "app/tools/active_tool.h"
#include "app/color.h"
#include "app/pref/preferences.h" #include "app/pref/preferences.h"
#include "app/tools/active_tool_observer.h" #include "app/tools/active_tool_observer.h"
#include "app/tools/ink.h" #include "app/tools/ink.h"
@ -76,24 +77,32 @@ Ink* ActiveToolManager::activeInk() const
Tool* tool = activeTool(); Tool* tool = activeTool();
Ink* ink = tool->getInk(m_rightClick ? 1: 0); Ink* ink = tool->getInk(m_rightClick ? 1: 0);
if (ink->isPaint() && !ink->isEffect()) { if (ink->isPaint() && !ink->isEffect()) {
tools::InkType inkType = Preferences::instance().tool(tool).ink(); const tools::InkType inkType = Preferences::instance().tool(tool).ink();
const char* id = nullptr; app::Color color;
switch (inkType) {
case tools::InkType::SIMPLE: {
id = tools::WellKnownInks::Paint;
#ifdef ENABLE_UI #ifdef ENABLE_UI
ColorBar* colorbar = ColorBar::instance(); ColorBar* colorbar = ColorBar::instance();
app::Color color = (m_rightClick ? colorbar->getBgColor(): color = (m_rightClick ? colorbar->getBgColor():
colorbar->getFgColor()); colorbar->getFgColor());
#endif
ink = adjustToolInkDependingOnSelectedInkType(ink, inkType, color);
}
return ink;
}
Ink* ActiveToolManager::adjustToolInkDependingOnSelectedInkType(
Ink* ink,
const InkType inkType,
const app::Color& color) const
{
if (ink->isPaint() && !ink->isEffect()) {
const char* id = nullptr;
switch (inkType) {
case tools::InkType::SIMPLE:
id = tools::WellKnownInks::Paint;
if (color.getAlpha() == 0) if (color.getAlpha() == 0)
id = tools::WellKnownInks::PaintCopy; id = tools::WellKnownInks::PaintCopy;
#endif
break; break;
}
case tools::InkType::ALPHA_COMPOSITING: case tools::InkType::ALPHA_COMPOSITING:
id = tools::WellKnownInks::Paint; id = tools::WellKnownInks::Paint;
break; break;
@ -107,11 +116,9 @@ Ink* ActiveToolManager::activeInk() const
id = tools::WellKnownInks::Shading; id = tools::WellKnownInks::Shading;
break; break;
} }
if (id) if (id)
ink = m_toolbox->getInkById(id); ink = m_toolbox->getInkById(id);
} }
return ink; return ink;
} }

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2020 Igara Studio S.A.
// Copyright (C) 2016 David Capello // Copyright (C) 2016 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -8,9 +9,12 @@
#define APP_TOOLS_ACTIVE_TOOL_H_INCLUDED #define APP_TOOLS_ACTIVE_TOOL_H_INCLUDED
#pragma once #pragma once
#include "app/tools/ink_type.h"
#include "obs/observable.h" #include "obs/observable.h"
namespace app { namespace app {
class Color;
namespace tools { namespace tools {
class ActiveToolObserver; class ActiveToolObserver;
@ -44,6 +48,11 @@ public:
void releaseButtons(); void releaseButtons();
void setSelectedTool(Tool* tool); void setSelectedTool(Tool* tool);
Ink* adjustToolInkDependingOnSelectedInkType(
Ink* ink,
const InkType inkType,
const app::Color& color) const;
private: private:
static bool isToolAffectedByRightClickMode(Tool* tool); static bool isToolAffectedByRightClickMode(Tool* tool);

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2020 Igara Studio S.A.
// Copyright (C) 2001-2015 David Capello // Copyright (C) 2001-2015 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -39,11 +40,24 @@ std::string ink_type_to_string_id(InkType inkType)
InkType string_id_to_ink_type(const std::string& s) InkType string_id_to_ink_type(const std::string& s)
{ {
if (s == "simple") return tools::InkType::SIMPLE; if (s == "simple")
if (s == "alpha_compositing") return tools::InkType::ALPHA_COMPOSITING; return tools::InkType::SIMPLE;
if (s == "copy_color") return tools::InkType::COPY_COLOR;
if (s == "lock_alpha") return tools::InkType::LOCK_ALPHA; if (s == "alpha_compositing" ||
if (s == "shading") return tools::InkType::SHADING; s == "alpha-compositing")
return tools::InkType::ALPHA_COMPOSITING;
if (s == "copy_color" ||
s == "copy-color")
return tools::InkType::COPY_COLOR;
if (s == "lock_alpha" ||
s == "lock-alpha")
return tools::InkType::LOCK_ALPHA;
if (s == "shading")
return tools::InkType::SHADING;
return tools::InkType::DEFAULT; return tools::InkType::DEFAULT;
} }