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
// Copyright (C) 2020 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
@ -11,7 +12,7 @@
#include "app/app.h"
#include "app/commands/command.h"
#include "app/commands/commands.h"
#include "app/commands/params.h"
#include "app/commands/new_params.h"
#include "app/i18n/strings.h"
#include "app/tools/ink_type.h"
#include "app/ui/context_bar.h"
@ -19,60 +20,42 @@
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:
SetInkTypeCommand();
protected:
bool onNeedsParams() const override { return true; }
void onLoadParams(const Params& params) override;
bool onChecked(Context* context) override;
void onExecute(Context* context) override;
std::string onGetFriendlyName() const override;
private:
tools::InkType m_type;
};
SetInkTypeCommand::SetInkTypeCommand()
: Command(CommandId::SetInkType(), CmdUIOnlyFlag)
, m_type(tools::InkType::DEFAULT)
: CommandWithNewParams(CommandId::SetInkType(), CmdUIOnlyFlag)
{
}
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)
{
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)
{
if (App::instance()->contextBar() != nullptr)
App::instance()->contextBar()->setInkType(m_type);
App::instance()->contextBar()->setInkType(params().type());
}
std::string SetInkTypeCommand::onGetFriendlyName() const
{
std::string ink;
switch (m_type) {
switch (params().type()) {
case tools::InkType::SIMPLE:
ink = Strings::inks_simple_ink();
break;

View File

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

View File

@ -282,9 +282,21 @@ int App_useTool(lua_State* L)
// Options to create the ToolLoop (tool, ink, color, opacity, etc.)
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
params.tool = App::instance()->activeToolManager()->activeTool();
params.ink = params.tool->getInk(0);
auto activeToolMgr = App::instance()->activeToolManager();
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");
if (type != LUA_TNIL) {
if (auto toolArg = get_tool_from_arg(L, -1)) {
@ -296,18 +308,12 @@ int App_useTool(lua_State* L)
}
lua_pop(L, 1);
// 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;
}
// Select ink by name
type = lua_getfield(L, 1, "ink");
if (type != LUA_TNIL)
params.inkType = get_value_from_lua<tools::InkType>(L, -1);
lua_pop(L, 1);
params.controller = params.tool->getController(params.button);
// Color
type = lua_getfield(L, 1, "color");
if (type != LUA_TNIL)
@ -325,6 +331,13 @@ int App_useTool(lua_State* L)
params.bg = params.fg;
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
type = lua_getfield(L, 1, "brush");
if (type != LUA_TNIL)

View File

@ -329,6 +329,16 @@ Engine::Engine()
setfield_integer(L, "NONE", doc::BrushPattern::PAINT_BRUSH);
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_pushvalue(L, -1);
lua_setglobal(L, "FilterChannels");

View File

@ -48,14 +48,14 @@ namespace doc {
class WithUserData;
}
namespace tools {
class Tool;
}
namespace app {
class Site;
namespace tools {
class Tool;
}
namespace script {
enum class FileAccessMode {
@ -146,7 +146,7 @@ namespace app {
void push_sprite_slices(lua_State* L, doc::Sprite* sprite);
void push_sprite_tags(lua_State* L, doc::Sprite* sprite);
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_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::frame_t get_frame_number_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);
// 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);
}
// ----------------------------------------------------------------------
// 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
@ -163,7 +180,6 @@ FOR_ENUM(app::gen::TimelinePosition)
FOR_ENUM(app::gen::WindowColorProfile)
FOR_ENUM(app::gen::ToGrayAlgorithm)
FOR_ENUM(app::tools::FreehandAlgorithm)
FOR_ENUM(app::tools::InkType)
FOR_ENUM(app::tools::RotationAlgorithm)
FOR_ENUM(doc::AniDir)
FOR_ENUM(doc::BrushPattern)

View File

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

View File

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

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2020 Igara Studio S.A.
// Copyright (C) 2001-2015 David Capello
//
// 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)
{
if (s == "simple") return tools::InkType::SIMPLE;
if (s == "alpha_compositing") return tools::InkType::ALPHA_COMPOSITING;
if (s == "copy_color") return tools::InkType::COPY_COLOR;
if (s == "lock_alpha") return tools::InkType::LOCK_ALPHA;
if (s == "shading") return tools::InkType::SHADING;
if (s == "simple")
return tools::InkType::SIMPLE;
if (s == "alpha_compositing" ||
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;
}