diff --git a/data/gui.xml b/data/gui.xml
index d7246a045..e1738d0b4 100644
--- a/data/gui.xml
+++ b/data/gui.xml
@@ -365,6 +365,9 @@
+
+
+
diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt
index 8f11db80d..a857b879b 100644
--- a/src/app/CMakeLists.txt
+++ b/src/app/CMakeLists.txt
@@ -227,6 +227,7 @@ add_library(app-lib
commands/cmd_palette_size.cpp
commands/cmd_paste.cpp
commands/cmd_paste_text.cpp
+ commands/cmd_pixel_perfect_mode.cpp
commands/cmd_play_animation.cpp
commands/cmd_refresh.cpp
commands/cmd_remove_frame.cpp
diff --git a/src/app/commands/cmd_pixel_perfect_mode.cpp b/src/app/commands/cmd_pixel_perfect_mode.cpp
new file mode 100644
index 000000000..1314f9f65
--- /dev/null
+++ b/src/app/commands/cmd_pixel_perfect_mode.cpp
@@ -0,0 +1,73 @@
+// Aseprite
+// Copyright (C) 2001-2015 David Capello
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+
+#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/pref/preferences.h"
+#include "app/tools/freehand_algorithm.h"
+#include "app/tools/tool.h"
+
+namespace app {
+
+class PixelPerfectModeCommand : public Command {
+public:
+ PixelPerfectModeCommand();
+ Command* clone() const override { return new PixelPerfectModeCommand(*this); }
+
+protected:
+ bool onEnabled(Context* context) override;
+ bool onChecked(Context* context) override;
+ void onExecute(Context* context) override;
+};
+
+PixelPerfectModeCommand::PixelPerfectModeCommand()
+ : Command("PixelPerfectMode",
+ "Switch Pixel Perfect Mode",
+ CmdUIOnlyFlag)
+{
+}
+
+bool PixelPerfectModeCommand::onEnabled(Context* ctx)
+{
+ return true;
+}
+
+bool PixelPerfectModeCommand::onChecked(Context* ctx)
+{
+ tools::Tool* tool = App::instance()->activeTool();
+ if (!tool)
+ return false;
+
+ auto& toolPref = Preferences::instance().tool(tool);
+ return (toolPref.freehandAlgorithm() == tools::FreehandAlgorithm::PIXEL_PERFECT);
+}
+
+void PixelPerfectModeCommand::onExecute(Context* ctx)
+{
+ tools::Tool* tool = App::instance()->activeTool();
+ if (!tool)
+ return;
+
+ auto& toolPref = Preferences::instance().tool(tool);
+ toolPref.freehandAlgorithm(
+ toolPref.freehandAlgorithm() == tools::FreehandAlgorithm::DEFAULT ?
+ tools::FreehandAlgorithm::PIXEL_PERFECT:
+ tools::FreehandAlgorithm::DEFAULT);
+}
+
+Command* CommandFactory::createPixelPerfectModeCommand()
+{
+ return new PixelPerfectModeCommand;
+}
+
+} // namespace app
diff --git a/src/app/commands/commands.h b/src/app/commands/commands.h
index 20416374e..44440305c 100644
--- a/src/app/commands/commands.h
+++ b/src/app/commands/commands.h
@@ -37,6 +37,9 @@ namespace app {
static CommandsModule* instance();
Command* getCommandByName(const char* name);
+
+ CommandsList::iterator begin() { return m_commands.begin(); }
+ CommandsList::iterator end() { return m_commands.end(); }
};
} // namespace app
diff --git a/src/app/commands/commands_list.h b/src/app/commands/commands_list.h
index 00c3edb10..0d488ce7a 100644
--- a/src/app/commands/commands_list.h
+++ b/src/app/commands/commands_list.h
@@ -84,6 +84,7 @@ FOR_EACH_COMMAND(PaletteEditor)
FOR_EACH_COMMAND(PaletteSize)
FOR_EACH_COMMAND(Paste)
FOR_EACH_COMMAND(PasteText)
+FOR_EACH_COMMAND(PixelPerfectMode)
FOR_EACH_COMMAND(PlayAnimation)
FOR_EACH_COMMAND(Redo)
FOR_EACH_COMMAND(Refresh)
diff --git a/src/app/ui/context_bar.cpp b/src/app/ui/context_bar.cpp
index 1916bda6c..ef1de8455 100644
--- a/src/app/ui/context_bar.cpp
+++ b/src/app/ui/context_bar.cpp
@@ -1125,6 +1125,15 @@ void ContextBar::onToolSetOpacity(const int& newOpacity)
m_inkOpacity->setTextf("%d", newOpacity);
}
+void ContextBar::onToolSetFreehandAlgorithm()
+{
+ Tool* tool = App::instance()->activeTool();
+ if (tool) {
+ m_freehandAlgo->setFreehandAlgorithm(
+ Preferences::instance().tool(tool).freehandAlgorithm());
+ }
+}
+
void ContextBar::onBrushSizeChange()
{
if (m_activeBrush->type() != kImageBrushType)
@@ -1188,6 +1197,7 @@ void ContextBar::updateForTool(tools::Tool* tool)
m_sizeConn = brushPref->size.AfterChange.connect(Bind(&ContextBar::onBrushSizeChange, this));
m_angleConn = brushPref->angle.AfterChange.connect(Bind(&ContextBar::onBrushAngleChange, this));
m_opacityConn = toolPref->opacity.AfterChange.connect(&ContextBar::onToolSetOpacity, this);
+ m_freehandAlgoConn = toolPref->freehandAlgorithm.AfterChange.connect(Bind(&ContextBar::onToolSetFreehandAlgorithm, this));
}
if (tool)
diff --git a/src/app/ui/context_bar.h b/src/app/ui/context_bar.h
index 1fa8cfa24..52ca071e4 100644
--- a/src/app/ui/context_bar.h
+++ b/src/app/ui/context_bar.h
@@ -78,6 +78,7 @@ namespace app {
protected:
void onPreferredSize(ui::PreferredSizeEvent& ev) override;
void onToolSetOpacity(const int& newOpacity);
+ void onToolSetFreehandAlgorithm();
private:
void onBrushSizeChange();
@@ -156,6 +157,7 @@ namespace app {
ScopedConnection m_sizeConn;
ScopedConnection m_angleConn;
ScopedConnection m_opacityConn;
+ ScopedConnection m_freehandAlgoConn;
};
} // namespace app
diff --git a/src/app/ui/keyboard_shortcuts.cpp b/src/app/ui/keyboard_shortcuts.cpp
index b4024ec25..2e295e99f 100644
--- a/src/app/ui/keyboard_shortcuts.cpp
+++ b/src/app/ui/keyboard_shortcuts.cpp
@@ -312,7 +312,7 @@ void KeyboardShortcuts::importFile(TiXmlElement* rootElement, KeySource source)
const char* command_key = get_shortcut(xmlKey);
bool removed = bool_attr_is_true(xmlKey, "removed");
- if (command_name && command_key) {
+ if (command_name) {
Command* command = CommandsModule::instance()->getCommandByName(command_name);
if (command) {
// Read context
@@ -339,11 +339,9 @@ void KeyboardShortcuts::importFile(TiXmlElement* rootElement, KeySource source)
xmlParam = xmlParam->NextSiblingElement();
}
- LOG(" - Shortcut for command `%s' <%s>\n", command_name, command_key);
-
// add the keyboard shortcut to the command
Key* key = this->command(command_name, params, keycontext);
- if (key) {
+ if (key && command_key) {
Accelerator accel(command_key);
if (!removed) {