Add "ui" param to MaskByColorCommand (fix #2774)

This commit is contained in:
Martín Capello 2024-11-06 11:31:57 -03:00 committed by David Capello
parent 4dc7ba6dc0
commit 2596af548a
2 changed files with 79 additions and 19 deletions

View File

@ -14,6 +14,7 @@
#include "app/color.h"
#include "app/color_utils.h"
#include "app/commands/command.h"
#include "app/commands/new_params.h"
#include "app/console.h"
#include "app/context.h"
#include "app/context_access.h"
@ -46,16 +47,38 @@ namespace app {
using namespace ui;
// Disable warning about usage of "this" in initializer list.
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
static const char* ConfigSection = "MaskColor";
struct MaskByColorParams : public NewParams {
Param<bool> ui { this, true, "ui" };
Param<app::Color> color { this, app::Color(), "color" };
Param<int> tolerance { this, 0, "tolerance" };
Param<gen::SelectionMode> mode { this, gen::SelectionMode::DEFAULT, "mode" };
};
class MaskByColorWindow : public ui::Window {
public:
MaskByColorWindow(const ContextReader& reader)
MaskByColorWindow(MaskByColorParams& params, const ContextReader& reader)
: Window(Window::WithTitleBar, Strings::mask_by_color_title())
, m_reader(&reader)
// Save original mask visibility to process it correctly in
// ADD/SUBTRACT/INTERSECT Selection Mode
, m_isOrigMaskVisible(reader.document()->isMaskVisible()) {
if (!params.color.isSet())
params.color(ColorBar::instance()->getFgColor());
if (!params.tolerance.isSet())
params.tolerance(get_config_int(ConfigSection, "Tolerance", 0));
if (!params.mode.isSet())
params.mode(Preferences::instance().selection.mode());
TooltipManager* tooltipManager = new TooltipManager();
addChild(tooltipManager);
auto box1 = new Box(VERTICAL);
@ -64,13 +87,14 @@ public:
auto box4 = new Box(HORIZONTAL | HOMOGENEOUS);
auto label_color = new Label(Strings::mask_by_color_label_color());
m_buttonColor = new ColorButton(
ColorBar::instance()->getFgColor(),
params.color(),
reader.sprite()->pixelFormat(),
ColorButtonOptions());
auto label_tolerance = new Label(Strings::mask_by_color_tolerance());
m_sliderTolerance = new Slider(0, 255, get_config_int(ConfigSection, "Tolerance", 0));
m_sliderTolerance = new Slider(0, 255, params.tolerance());
m_selMode = new SelModeField;
m_selMode->setSelectionMode(params.mode());
m_selMode->setupTooltips(tooltipManager);
m_checkPreview = new CheckBox(Strings::mask_by_color_preview());
@ -214,6 +238,7 @@ bool MaskByColorCommand::onEnabled(Context* context)
void MaskByColorCommand::onExecute(Context* context)
{
const bool ui = (params().ui() && context->isUIAvailable());
const ContextReader reader(context);
const Sprite* sprite = reader.sprite();
@ -225,37 +250,50 @@ void MaskByColorCommand::onExecute(Context* context)
if (!image)
return;
MaskByColorWindow window(reader);
// Save original mask visibility to process it correctly in
// ADD/SUBTRACT/INTERSECT Selection Mode
bool isOrigMaskVisible = reader.document()->isMaskVisible();
bool apply = true;
auto& params = this->params();
if (ui) {
MaskByColorWindow window(params, reader);
// Load window configuration
load_window_pos(&window, ConfigSection);
// Open the window
window.openWindowInForeground();
bool apply = window.accepted();
// Save window configuration.
save_window_pos(&window, ConfigSection);
apply = window.accepted();
if (apply) {
params.color(window.getColor());
params.mode(window.getSelectionMode());
params.tolerance(window.getTolerance());
set_config_int(ConfigSection, "Tolerance", params.tolerance());
set_config_bool(ConfigSection, "Preview", window.isPreviewChecked());
}
}
ContextWriter writer(reader);
Doc* document(writer.document());
if (apply) {
int color = color_utils::color_for_image(window.getColor(),
int color = color_utils::color_for_image(params.color(),
sprite->pixelFormat());
int tolerance = window.getTolerance();
Tx tx(writer, "Mask by Color", DoesntModifyDocument);
std::unique_ptr<Mask> mask(generateMask(*document->mask(),
isOrigMaskVisible,
image, xpos, ypos,
window.getSelectionMode(),
color, tolerance));
params.mode(),
color, params.tolerance()));
tx(new cmd::SetMask(document, mask.get()));
tx.commit();
set_config_int(ConfigSection, "Tolerance", tolerance);
set_config_bool(ConfigSection, "Preview", window.isPreviewChecked());
}
else {
document->generateMaskBoundaries();
@ -263,9 +301,6 @@ void MaskByColorCommand::onExecute(Context* context)
// Update boundaries and editors.
update_screen_for_document(document);
// Save window configuration.
save_window_pos(&window, ConfigSection);
}
void MaskByColorWindow::maskPreview()

View File

@ -12,6 +12,7 @@
#include "app/color.h"
#include "app/doc_exporter.h"
#include "app/pref/preferences.h"
#include "app/sprite_sheet_type.h"
#include "app/tools/ink_type.h"
#include "base/convert_to.h"
@ -241,6 +242,21 @@ void Param<doc::RgbMapAlgorithm>::fromString(const std::string& value)
setValue(doc::RgbMapAlgorithm::DEFAULT);
}
template<>
void Param<gen::SelectionMode>::fromString(const std::string& value)
{
if (base::utf8_icmp(value, "replace") == 0)
setValue(gen::SelectionMode::REPLACE);
else if (base::utf8_icmp(value, "add") == 0)
setValue(gen::SelectionMode::ADD);
else if (base::utf8_icmp(value, "subtract") == 0)
setValue(gen::SelectionMode::SUBTRACT);
else if (base::utf8_icmp(value, "intersect") == 0)
setValue(gen::SelectionMode::INTERSECT);
else
setValue(gen::SelectionMode::DEFAULT);
}
//////////////////////////////////////////////////////////////////////
// Convert values from Lua
//////////////////////////////////////////////////////////////////////
@ -405,6 +421,15 @@ void Param<doc::RgbMapAlgorithm>::fromLua(lua_State* L, int index)
setValue((doc::RgbMapAlgorithm)lua_tointeger(L, index));
}
template<>
void Param<gen::SelectionMode>::fromLua(lua_State* L, int index)
{
if (lua_type(L, index) == LUA_TSTRING)
fromString(lua_tostring(L, index));
else
setValue((gen::SelectionMode)lua_tointeger(L, index));
}
void CommandWithNewParamsBase::loadParamsFromLuaTable(lua_State* L, int index)
{
onResetValues();