mirror of https://github.com/aseprite/aseprite.git
132 lines
4.1 KiB
C++
132 lines
4.1 KiB
C++
// Aseprite
|
|
// Copyright (C) 2018-2024 Igara Studio S.A.
|
|
// Copyright (C) 2001-2017 David Capello
|
|
//
|
|
// 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/app.h"
|
|
#include "app/commands/command.h"
|
|
#include "app/commands/params.h"
|
|
#include "app/context.h"
|
|
#include "app/doc.h"
|
|
#include "app/i18n/strings.h"
|
|
#include "app/pref/preferences.h"
|
|
#include "app/ui/context_bar.h"
|
|
|
|
namespace app {
|
|
|
|
class SymmetryModeCommand : public Command {
|
|
public:
|
|
SymmetryModeCommand();
|
|
|
|
protected:
|
|
void onLoadParams(const Params& params) override;
|
|
bool onEnabled(Context* context) override;
|
|
bool onChecked(Context* context) override;
|
|
void onExecute(Context* context) override;
|
|
std::string onGetFriendlyName() const override;
|
|
|
|
private:
|
|
app::gen::SymmetryMode m_mode = app::gen::SymmetryMode::NONE;
|
|
};
|
|
|
|
SymmetryModeCommand::SymmetryModeCommand() : Command(CommandId::SymmetryMode())
|
|
{
|
|
}
|
|
|
|
std::string SymmetryModeCommand::onGetFriendlyName() const
|
|
{
|
|
switch (m_mode) {
|
|
case app::gen::SymmetryMode::HORIZONTAL: return Strings::symmetry_toggle_horizontal();
|
|
case app::gen::SymmetryMode::VERTICAL: return Strings::symmetry_toggle_vertical();
|
|
case app::gen::SymmetryMode::RIGHT_DIAG: return Strings::symmetry_toggle_right_diagonal();
|
|
case app::gen::SymmetryMode::LEFT_DIAG: return Strings::symmetry_toggle_left_diagonal();
|
|
default: return Strings::symmetry_toggle();
|
|
}
|
|
}
|
|
|
|
void SymmetryModeCommand::onLoadParams(const Params& params)
|
|
{
|
|
std::string mode = params.get("orientation");
|
|
if (mode == "vertical")
|
|
m_mode = app::gen::SymmetryMode::VERTICAL;
|
|
else if (mode == "horizontal")
|
|
m_mode = app::gen::SymmetryMode::HORIZONTAL;
|
|
else if (mode == "right_diagonal")
|
|
m_mode = app::gen::SymmetryMode::RIGHT_DIAG;
|
|
else if (mode == "left_diagonal")
|
|
m_mode = app::gen::SymmetryMode::LEFT_DIAG;
|
|
else
|
|
m_mode = app::gen::SymmetryMode::NONE;
|
|
}
|
|
|
|
bool SymmetryModeCommand::onEnabled(Context* ctx)
|
|
{
|
|
return ctx->checkFlags(ContextFlags::ActiveDocumentIsWritable | ContextFlags::HasActiveSprite);
|
|
}
|
|
|
|
bool SymmetryModeCommand::onChecked(Context* ctx)
|
|
{
|
|
return Preferences::instance().symmetryMode.enabled();
|
|
}
|
|
|
|
void SymmetryModeCommand::onExecute(Context* ctx)
|
|
{
|
|
auto& enabled = Preferences::instance().symmetryMode.enabled;
|
|
// When the m_mode is NONE, it toggles the whole symmetry controls in
|
|
// the context bar.
|
|
if (m_mode == app::gen::SymmetryMode::NONE) {
|
|
enabled(!enabled());
|
|
}
|
|
// In other case it toggles the specific document symmetry specified
|
|
// in m_mode.
|
|
else {
|
|
Doc* doc = ctx->activeDocument();
|
|
DocumentPreferences& docPref = Preferences::instance().document(doc);
|
|
const app::gen::SymmetryMode actual = docPref.symmetry.mode();
|
|
|
|
// If the symmetry options are hidden, we'll always show them and
|
|
// activate the m_mode symmetry. We cannot just toggle the
|
|
// symmetry when the options aren't visible in the context bar,
|
|
// because if m_mode is checked, this would cause to show the
|
|
// symmetry options in the context bar but with a unchecked m_mode
|
|
// symmetry.
|
|
if (!enabled()) {
|
|
docPref.symmetry.mode(app::gen::SymmetryMode(int(m_mode) | int(actual)));
|
|
enabled(true);
|
|
}
|
|
// If the symmetry options are visible, we just switch the m_mode
|
|
// symmetry.
|
|
else {
|
|
docPref.symmetry.mode(app::gen::SymmetryMode(int(m_mode) ^ int(actual)));
|
|
}
|
|
|
|
// Redraw all editors
|
|
//
|
|
// TODO It looks like only the current editor shows the symmetry,
|
|
// so it's not necessary to invalidate all editors (only the
|
|
// current one).
|
|
doc->notifyGeneralUpdate();
|
|
|
|
// Redraw the buttons in the context bar.
|
|
//
|
|
// TODO Same with context bar, in the future the context bar could
|
|
// be listening the DocPref changes to be automatically
|
|
// invalidated (like it already does with symmetryMode.enabled)
|
|
if (App::instance()->contextBar())
|
|
App::instance()->contextBar()->updateForActiveTool();
|
|
}
|
|
}
|
|
|
|
Command* CommandFactory::createSymmetryModeCommand()
|
|
{
|
|
return new SymmetryModeCommand;
|
|
}
|
|
|
|
} // namespace app
|