Move everything related to tools in "tools" namespace.

+ Splitted tools/tool.h|cpp in several files (ink.h, intertwine.h, etc.).
This commit is contained in:
David Capello 2011-04-02 10:47:03 -03:00
parent 3c3136235f
commit 1fd011c20b
38 changed files with 1056 additions and 683 deletions

View File

@ -229,8 +229,10 @@ add_library(aseprite-library
skin/skin_theme.cpp skin/skin_theme.cpp
skin/skin_property.cpp skin/skin_property.cpp
skin/skin_slider_property.cpp skin/skin_slider_property.cpp
tools/tool.cpp tools/intertwine.cpp
tools/toolbox.cpp tools/point_shape.cpp
tools/tool_box.cpp
tools/tool_loop_manager.cpp
undoers/add_cel.cpp undoers/add_cel.cpp
undoers/add_image.cpp undoers/add_image.cpp
undoers/add_layer.cpp undoers/add_layer.cpp

View File

@ -47,7 +47,7 @@
#include "raster/palette.h" #include "raster/palette.h"
#include "raster/sprite.h" #include "raster/sprite.h"
#include "recent_files.h" #include "recent_files.h"
#include "tools/toolbox.h" #include "tools/tool_box.h"
#include "ui_context.h" #include "ui_context.h"
#include "util/boundary.h" #include "util/boundary.h"
#include "util/render.h" #include "util/render.h"
@ -79,7 +79,7 @@ class App::Modules
public: public:
// ASE Modules // ASE Modules
FileSystemModule m_file_system_module; FileSystemModule m_file_system_module;
ToolBox m_toolbox; tools::ToolBox m_toolbox;
CommandsModule m_commands_modules; CommandsModule m_commands_modules;
UIContext m_ui_context; UIContext m_ui_context;
RecentFiles m_recent_files; RecentFiles m_recent_files;
@ -339,7 +339,7 @@ LoggerModule* App::getLogger() const
return m_loggerModule; return m_loggerModule;
} }
ToolBox* App::getToolBox() const tools::ToolBox* App::getToolBox() const
{ {
ASSERT(m_modules != NULL); ASSERT(m_modules != NULL);
return &m_modules->m_toolbox; return &m_modules->m_toolbox;

View File

@ -37,7 +37,8 @@ class Params;
class RecentFiles; class RecentFiles;
class StatusBar; class StatusBar;
class Tabs; class Tabs;
class ToolBox;
namespace tools { class ToolBox; }
class App class App
{ {
@ -60,7 +61,7 @@ public:
int run(); int run();
LoggerModule* getLogger() const; LoggerModule* getLogger() const;
ToolBox* getToolBox() const; tools::ToolBox* getToolBox() const;
RecentFiles* getRecentFiles() const; RecentFiles* getRecentFiles() const;
// App Signals // App Signals

View File

@ -62,7 +62,7 @@ void ChangePenCommand::onLoadParams(Params* params)
void ChangePenCommand::onExecute(Context* context) void ChangePenCommand::onExecute(Context* context)
{ {
Tool* current_tool = context->getSettings()->getCurrentTool(); tools::Tool* current_tool = context->getSettings()->getCurrentTool();
IToolSettings* tool_settings = context->getSettings()->getToolSettings(current_tool); IToolSettings* tool_settings = context->getSettings()->getToolSettings(current_tool);
IPenSettings* pen = tool_settings->getPen(); IPenSettings* pen = tool_settings->getPen();

View File

@ -18,13 +18,12 @@
#include "config.h" #include "config.h"
#include <allegro.h>
#include "app.h" #include "app.h"
#include "base/bind.h" #include "base/bind.h"
#include "commands/command.h" #include "commands/command.h"
#include "commands/commands.h" #include "commands/commands.h"
#include "console.h" #include "console.h"
#include "document_wrappers.h"
#include "gfx/size.h" #include "gfx/size.h"
#include "gui/gui.h" #include "gui/gui.h"
#include "modules/editors.h" #include "modules/editors.h"
@ -37,7 +36,8 @@
#include "raster/sprite.h" #include "raster/sprite.h"
#include "settings/settings.h" #include "settings/settings.h"
#include "skin/skin_parts.h" #include "skin/skin_parts.h"
#include "document_wrappers.h" #include "tools/ink.h"
#include "tools/point_shape.h"
#include "tools/tool.h" #include "tools/tool.h"
#include "ui_context.h" #include "ui_context.h"
#include "widgets/color_button.h" #include "widgets/color_button.h"
@ -45,7 +45,10 @@
#include "widgets/groupbut.h" #include "widgets/groupbut.h"
#include "widgets/statebar.h" #include "widgets/statebar.h"
#include <allegro.h>
using namespace gfx; using namespace gfx;
using namespace tools;
static Frame* window = NULL; static Frame* window = NULL;

View File

@ -50,7 +50,7 @@
#include "skin/skin_property.h" #include "skin/skin_property.h"
#include "skin/skin_theme.h" #include "skin/skin_theme.h"
#include "document_wrappers.h" #include "document_wrappers.h"
#include "tools/toolbox.h" #include "tools/tool_box.h"
#include "ui_context.h" #include "ui_context.h"
#include "widgets/editor/editor.h" #include "widgets/editor/editor.h"
#include "widgets/statebar.h" #include "widgets/statebar.h"
@ -101,7 +101,7 @@ struct Shortcut
ShortcutType type; ShortcutType type;
union { union {
Command* command; Command* command;
Tool* tool; tools::Tool* tool;
}; };
Params* params; Params* params;
@ -115,8 +115,8 @@ struct Shortcut
}; };
static Shortcut* get_keyboard_shortcut_for_command(const char* command_name, Params* params); static Shortcut* get_keyboard_shortcut_for_command(const char* command_name, Params* params);
static Shortcut* get_keyboard_shortcut_for_tool(Tool* tool); static Shortcut* get_keyboard_shortcut_for_tool(tools::Tool* tool);
static Shortcut* get_keyboard_shortcut_for_quicktool(Tool* tool); static Shortcut* get_keyboard_shortcut_for_quicktool(tools::Tool* tool);
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@ -907,7 +907,7 @@ JAccel add_keyboard_shortcut_to_execute_command(const char* shortcut_string, con
return shortcut->accel; return shortcut->accel;
} }
JAccel add_keyboard_shortcut_to_change_tool(const char* shortcut_string, Tool* tool) JAccel add_keyboard_shortcut_to_change_tool(const char* shortcut_string, tools::Tool* tool)
{ {
Shortcut* shortcut = get_keyboard_shortcut_for_tool(tool); Shortcut* shortcut = get_keyboard_shortcut_for_tool(tool);
@ -922,7 +922,7 @@ JAccel add_keyboard_shortcut_to_change_tool(const char* shortcut_string, Tool* t
return shortcut->accel; return shortcut->accel;
} }
JAccel add_keyboard_shortcut_to_quicktool(const char* shortcut_string, Tool* tool) JAccel add_keyboard_shortcut_to_quicktool(const char* shortcut_string, tools::Tool* tool)
{ {
Shortcut* shortcut = get_keyboard_shortcut_for_quicktool(tool); Shortcut* shortcut = get_keyboard_shortcut_for_quicktool(tool);
@ -962,7 +962,7 @@ JAccel get_accel_to_execute_command(const char* command_name, Params* params)
return NULL; return NULL;
} }
JAccel get_accel_to_change_tool(Tool* tool) JAccel get_accel_to_change_tool(tools::Tool* tool)
{ {
Shortcut* shortcut = get_keyboard_shortcut_for_tool(tool); Shortcut* shortcut = get_keyboard_shortcut_for_tool(tool);
if (shortcut) if (shortcut)
@ -971,12 +971,12 @@ JAccel get_accel_to_change_tool(Tool* tool)
return NULL; return NULL;
} }
Tool* get_selected_quicktool() tools::Tool* get_selected_quicktool()
{ {
ToolBox* toolbox = App::instance()->getToolBox(); tools::ToolBox* toolbox = App::instance()->getToolBox();
// Iterate over all tools // Iterate over all tools
for (ToolIterator it = toolbox->begin(); it != toolbox->end(); ++it) { for (tools::ToolIterator it = toolbox->begin(); it != toolbox->end(); ++it) {
Shortcut* shortcut = get_keyboard_shortcut_for_quicktool(*it); Shortcut* shortcut = get_keyboard_shortcut_for_quicktool(*it);
// Collect all tools with the pressed keyboard-shortcut // Collect all tools with the pressed keyboard-shortcut
@ -1050,7 +1050,7 @@ static Shortcut* get_keyboard_shortcut_for_command(const char* command_name, Par
return NULL; return NULL;
} }
static Shortcut* get_keyboard_shortcut_for_tool(Tool* tool) static Shortcut* get_keyboard_shortcut_for_tool(tools::Tool* tool)
{ {
for (std::vector<Shortcut*>::iterator for (std::vector<Shortcut*>::iterator
it = shortcuts->begin(); it != shortcuts->end(); ++it) { it = shortcuts->begin(); it != shortcuts->end(); ++it) {
@ -1065,7 +1065,7 @@ static Shortcut* get_keyboard_shortcut_for_tool(Tool* tool)
return NULL; return NULL;
} }
static Shortcut* get_keyboard_shortcut_for_quicktool(Tool* tool) static Shortcut* get_keyboard_shortcut_for_quicktool(tools::Tool* tool)
{ {
for (std::vector<Shortcut*>::iterator for (std::vector<Shortcut*>::iterator
it = shortcuts->begin(); it != shortcuts->end(); ++it) { it = shortcuts->begin(); it != shortcuts->end(); ++it) {
@ -1182,13 +1182,13 @@ static bool manager_msg_proc(JWidget widget, JMessage msg)
switch (shortcut->type) { switch (shortcut->type) {
case Shortcut_ChangeTool: { case Shortcut_ChangeTool: {
Tool* current_tool = UIContext::instance()->getSettings()->getCurrentTool(); tools::Tool* current_tool = UIContext::instance()->getSettings()->getCurrentTool();
Tool* select_this_tool = shortcut->tool; tools::Tool* select_this_tool = shortcut->tool;
ToolBox* toolbox = App::instance()->getToolBox(); tools::ToolBox* toolbox = App::instance()->getToolBox();
std::vector<Tool*> possibles; std::vector<tools::Tool*> possibles;
// Iterate over all tools // Iterate over all tools
for (ToolIterator it = toolbox->begin(); it != toolbox->end(); ++it) { for (tools::ToolIterator it = toolbox->begin(); it != toolbox->end(); ++it) {
Shortcut* shortcut = get_keyboard_shortcut_for_tool(*it); Shortcut* shortcut = get_keyboard_shortcut_for_tool(*it);
// Collect all tools with the pressed keyboard-shortcut // Collect all tools with the pressed keyboard-shortcut

View File

@ -33,9 +33,10 @@ class Document;
class Frame; class Frame;
class Params; class Params;
class RadioButton; class RadioButton;
class Tool;
class Widget; class Widget;
namespace tools { class Tool; }
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
class widget_file_not_found : public base::Exception class widget_file_not_found : public base::Exception
@ -109,13 +110,13 @@ CheckBox* check_button_new(const char* text, int b1, int b2, int b3, int b4);
// Keyboard shortcuts // Keyboard shortcuts
JAccel add_keyboard_shortcut_to_execute_command(const char* shortcut, const char* command_name, Params* params); JAccel add_keyboard_shortcut_to_execute_command(const char* shortcut, const char* command_name, Params* params);
JAccel add_keyboard_shortcut_to_change_tool(const char* shortcut, Tool* tool); JAccel add_keyboard_shortcut_to_change_tool(const char* shortcut, tools::Tool* tool);
JAccel add_keyboard_shortcut_to_quicktool(const char* shortcut, Tool* tool); JAccel add_keyboard_shortcut_to_quicktool(const char* shortcut, tools::Tool* tool);
Command* get_command_from_key_message(JMessage msg); Command* get_command_from_key_message(JMessage msg);
JAccel get_accel_to_execute_command(const char* command, Params* params = NULL); JAccel get_accel_to_execute_command(const char* command, Params* params = NULL);
JAccel get_accel_to_change_tool(Tool* tool); JAccel get_accel_to_change_tool(tools::Tool* tool);
Tool* get_selected_quicktool(); tools::Tool* get_selected_quicktool();
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Monitors // Monitors

View File

@ -33,7 +33,7 @@
#include "gui_xml.h" #include "gui_xml.h"
#include "modules/gui.h" #include "modules/gui.h"
#include "modules/rootmenu.h" #include "modules/rootmenu.h"
#include "tools/toolbox.h" #include "tools/tool_box.h"
#include "util/filetoks.h" #include "util/filetoks.h"
#include "widgets/menuitem.h" #include "widgets/menuitem.h"
@ -190,7 +190,7 @@ static int load_root_menu()
const char* tool_key = xmlKey->Attribute("shortcut"); const char* tool_key = xmlKey->Attribute("shortcut");
if (tool_id && tool_key) { if (tool_id && tool_key) {
Tool* tool = App::instance()->getToolBox()->getToolById(tool_id); tools::Tool* tool = App::instance()->getToolBox()->getToolById(tool_id);
if (tool) { if (tool) {
PRINTF(" - Shortcut for tool `%s': <%s>\n", tool_id, tool_key); PRINTF(" - Shortcut for tool `%s': <%s>\n", tool_id, tool_key);
add_keyboard_shortcut_to_change_tool(tool_key, tool); add_keyboard_shortcut_to_change_tool(tool_key, tool);
@ -217,7 +217,7 @@ static int load_root_menu()
const char* tool_key = xmlKey->Attribute("shortcut"); const char* tool_key = xmlKey->Attribute("shortcut");
if (tool_id && tool_key) { if (tool_id && tool_key) {
Tool* tool = App::instance()->getToolBox()->getToolById(tool_id); tools::Tool* tool = App::instance()->getToolBox()->getToolById(tool_id);
if (tool) { if (tool) {
PRINTF(" - Shortcut for quicktool `%s': <%s>\n", tool_id, tool_key); PRINTF(" - Shortcut for quicktool `%s': <%s>\n", tool_id, tool_key);
add_keyboard_shortcut_to_quicktool(tool_key, tool); add_keyboard_shortcut_to_quicktool(tool_key, tool);

View File

@ -26,7 +26,8 @@
class IToolSettings; class IToolSettings;
class IPenSettings; class IPenSettings;
class Tool;
namespace tools { class Tool; }
// Settings used in tool <-> drawing <-> editor stuff // Settings used in tool <-> drawing <-> editor stuff
class ISettings class ISettings
@ -38,12 +39,12 @@ public:
virtual Color getFgColor() = 0; virtual Color getFgColor() = 0;
virtual Color getBgColor() = 0; virtual Color getBgColor() = 0;
virtual Tool* getCurrentTool() = 0; virtual tools::Tool* getCurrentTool() = 0;
virtual TiledMode getTiledMode() = 0; virtual TiledMode getTiledMode() = 0;
virtual void setFgColor(const Color& color) = 0; virtual void setFgColor(const Color& color) = 0;
virtual void setBgColor(const Color& color) = 0; virtual void setBgColor(const Color& color) = 0;
virtual void setCurrentTool(Tool* tool) = 0; virtual void setCurrentTool(tools::Tool* tool) = 0;
virtual void setTiledMode(TiledMode mode) = 0; virtual void setTiledMode(TiledMode mode) = 0;
// Grid settings // Grid settings
@ -82,7 +83,7 @@ public:
// Tools settings // Tools settings
virtual IToolSettings* getToolSettings(Tool* tool) = 0; virtual IToolSettings* getToolSettings(tools::Tool* tool) = 0;
}; };

View File

@ -18,17 +18,19 @@
#include "config.h" #include "config.h"
#include <allegro/color.h> #include "settings/ui_settings_impl.h"
#include <string>
#include "app.h" #include "app.h"
#include "core/cfg.h" #include "core/cfg.h"
#include "settings/ui_settings_impl.h" #include "tools/point_shape.h"
#include "ui_context.h"
#include "tools/tool.h" #include "tools/tool.h"
#include "tools/toolbox.h" #include "tools/tool_box.h"
#include "ui_context.h"
#include "widgets/color_bar.h" #include "widgets/color_bar.h"
#include <allegro/color.h>
#include <string>
using namespace gfx; using namespace gfx;
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@ -87,7 +89,7 @@ Color UISettingsImpl::getBgColor()
return app_get_colorbar()->getBgColor(); return app_get_colorbar()->getBgColor();
} }
Tool* UISettingsImpl::getCurrentTool() tools::Tool* UISettingsImpl::getCurrentTool()
{ {
if (!m_currentTool) if (!m_currentTool)
m_currentTool = App::instance()->getToolBox()->getToolById("pencil"); m_currentTool = App::instance()->getToolBox()->getToolById("pencil");
@ -110,7 +112,7 @@ void UISettingsImpl::setBgColor(const Color& color)
app_get_colorbar()->setFgColor(color); app_get_colorbar()->setFgColor(color);
} }
void UISettingsImpl::setCurrentTool(Tool* tool) void UISettingsImpl::setCurrentTool(tools::Tool* tool)
{ {
if (m_currentTool != tool) { if (m_currentTool != tool) {
// Fire PenSizeBeforeChange signal (maybe the new selected tool has a different pen size) // Fire PenSizeBeforeChange signal (maybe the new selected tool has a different pen size)
@ -308,7 +310,7 @@ public:
class UIToolSettingsImpl : public IToolSettings class UIToolSettingsImpl : public IToolSettings
{ {
Tool* m_tool; tools::Tool* m_tool;
UIPenSettingsImpl m_pen; UIPenSettingsImpl m_pen;
int m_opacity; int m_opacity;
int m_tolerance; int m_tolerance;
@ -319,7 +321,7 @@ class UIToolSettingsImpl : public IToolSettings
public: public:
UIToolSettingsImpl(Tool* tool) UIToolSettingsImpl(tools::Tool* tool)
: m_tool(tool) : m_tool(tool)
{ {
std::string cfg_section(getCfgSection()); std::string cfg_section(getCfgSection());
@ -387,7 +389,7 @@ private:
} }
}; };
IToolSettings* UISettingsImpl::getToolSettings(Tool* tool) IToolSettings* UISettingsImpl::getToolSettings(tools::Tool* tool)
{ {
ASSERT(tool != NULL); ASSERT(tool != NULL);

View File

@ -33,12 +33,12 @@ public:
Color getFgColor(); Color getFgColor();
Color getBgColor(); Color getBgColor();
Tool* getCurrentTool(); tools::Tool* getCurrentTool();
TiledMode getTiledMode(); TiledMode getTiledMode();
void setFgColor(const Color& color); void setFgColor(const Color& color);
void setBgColor(const Color& color); void setBgColor(const Color& color);
void setCurrentTool(Tool* tool); void setCurrentTool(tools::Tool* tool);
void setTiledMode(TiledMode mode); void setTiledMode(TiledMode mode);
// Grid settings // Grid settings
@ -77,10 +77,10 @@ public:
// Tools settings // Tools settings
IToolSettings* getToolSettings(Tool* tool); IToolSettings* getToolSettings(tools::Tool* tool);
private: private:
Tool* m_currentTool; tools::Tool* m_currentTool;
TiledMode m_tiledMode; TiledMode m_tiledMode;
bool m_use_onionskin; bool m_use_onionskin;
int m_prev_frames_onionskin; int m_prev_frames_onionskin;

50
src/tools/controller.h Normal file
View File

@ -0,0 +1,50 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2011 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TOOLS_CONTROLLER_H_INCLUDED
#define TOOLS_CONTROLLER_H_INCLUDED
#include "gfx/point.h"
#include <string>
#include <vector>
namespace tools {
class ToolLoop;
// This class controls user input.
class Controller
{
public:
typedef std::vector<gfx::Point> Points;
virtual ~Controller() { }
virtual bool canSnapToGrid() { return true; }
virtual void pressButton(Points& points, const gfx::Point& point) = 0;
virtual bool releaseButton(Points& points, const gfx::Point& point) = 0;
virtual void movement(ToolLoop* loop, Points& points, const gfx::Point& point) = 0;
virtual void getPointsToInterwine(const Points& input, Points& output) = 0;
virtual void getStatusBarText(const Points& points, std::string& text) = 0;
};
} // namespace tools
#endif // TOOLS_TOOL_INK_H_INCLUDED

View File

@ -24,22 +24,22 @@
#endif #endif
// Controls clicks for tools like pencil // Controls clicks for tools like pencil
class FreehandController : public ToolController class FreehandController : public Controller
{ {
public: public:
void pressButton(std::vector<Point>& points, const Point& point) void pressButton(Points& points, const Point& point)
{ {
points.push_back(point); points.push_back(point);
} }
bool releaseButton(std::vector<Point>& points, const Point& point) bool releaseButton(Points& points, const Point& point)
{ {
return false; return false;
} }
void movement(IToolLoop* loop, std::vector<Point>& points, const Point& point) void movement(ToolLoop* loop, Points& points, const Point& point)
{ {
points.push_back(point); points.push_back(point);
} }
void getPointsToInterwine(const std::vector<Point>& input, std::vector<Point>& output) void getPointsToInterwine(const Points& input, Points& output)
{ {
if (input.size() == 1) { if (input.size() == 1) {
output.push_back(input[0]); output.push_back(input[0]);
@ -49,7 +49,7 @@ public:
output.push_back(input[input.size()-1]); output.push_back(input[input.size()-1]);
} }
} }
void getStatusBarText(const std::vector<Point>& points, std::string& text) void getStatusBarText(const Points& points, std::string& text)
{ {
char buf[1024]; char buf[1024];
sprintf(buf, "Start %3d %3d End %3d %3d", sprintf(buf, "Start %3d %3d End %3d %3d",
@ -61,22 +61,22 @@ public:
}; };
// Controls clicks for tools like line // Controls clicks for tools like line
class TwoPointsController : public ToolController class TwoPointsController : public Controller
{ {
Point m_center; Point m_center;
public: public:
void pressButton(std::vector<Point>& points, const Point& point) void pressButton(Points& points, const Point& point)
{ {
m_center = point; m_center = point;
points.push_back(point); points.push_back(point);
points.push_back(point); points.push_back(point);
} }
bool releaseButton(std::vector<Point>& points, const Point& point) bool releaseButton(Points& points, const Point& point)
{ {
return false; return false;
} }
void movement(IToolLoop* loop, std::vector<Point>& points, const Point& point) void movement(ToolLoop* loop, Points& points, const Point& point)
{ {
points[1] = point; points[1] = point;
@ -136,12 +136,12 @@ public:
else else
points[0] = m_center; points[0] = m_center;
} }
void getPointsToInterwine(const std::vector<Point>& input, std::vector<Point>& output) void getPointsToInterwine(const Points& input, Points& output)
{ {
output.push_back(input[0]); output.push_back(input[0]);
output.push_back(input[1]); output.push_back(input[1]);
} }
void getStatusBarText(const std::vector<Point>& points, std::string& text) void getStatusBarText(const Points& points, std::string& text)
{ {
char buf[1024]; char buf[1024];
sprintf(buf, "Start %3d %3d End %3d %3d (Size %3d %3d) Angle %.1f", sprintf(buf, "Start %3d %3d End %3d %3d (Size %3d %3d) Angle %.1f",
@ -156,15 +156,15 @@ public:
}; };
// Controls clicks for tools like polygon // Controls clicks for tools like polygon
class PointByPointController : public ToolController class PointByPointController : public Controller
{ {
public: public:
void pressButton(std::vector<Point>& points, const Point& point) void pressButton(Points& points, const Point& point)
{ {
points.push_back(point); points.push_back(point);
points.push_back(point); points.push_back(point);
} }
bool releaseButton(std::vector<Point>& points, const Point& point) bool releaseButton(Points& points, const Point& point)
{ {
if (points[points.size()-2] == point && if (points[points.size()-2] == point &&
points[points.size()-1] == point) points[points.size()-1] == point)
@ -172,15 +172,15 @@ public:
else else
return true; // Continue adding points return true; // Continue adding points
} }
void movement(IToolLoop* loop, std::vector<Point>& points, const Point& point) void movement(ToolLoop* loop, Points& points, const Point& point)
{ {
points[points.size()-1] = point; points[points.size()-1] = point;
} }
void getPointsToInterwine(const std::vector<Point>& input, std::vector<Point>& output) void getPointsToInterwine(const Points& input, Points& output)
{ {
output = input; output = input;
} }
void getStatusBarText(const std::vector<Point>& points, std::string& text) void getStatusBarText(const Points& points, std::string& text)
{ {
char buf[1024]; char buf[1024];
sprintf(buf, "Start %3d %3d End %3d %3d", sprintf(buf, "Start %3d %3d End %3d %3d",
@ -191,30 +191,30 @@ public:
} }
}; };
class OnePointController : public ToolController class OnePointController : public Controller
{ {
public: public:
// Do not apply grid to "one point tools" (e.g. magic wand, flood fill, etc.) // Do not apply grid to "one point tools" (e.g. magic wand, flood fill, etc.)
bool canSnapToGrid() { return false; } bool canSnapToGrid() { return false; }
void pressButton(std::vector<Point>& points, const Point& point) void pressButton(Points& points, const Point& point)
{ {
if (points.size() == 0) if (points.size() == 0)
points.push_back(point); points.push_back(point);
} }
bool releaseButton(std::vector<Point>& points, const Point& point) bool releaseButton(Points& points, const Point& point)
{ {
return false; return false;
} }
void movement(IToolLoop* loop, std::vector<Point>& points, const Point& point) void movement(ToolLoop* loop, Points& points, const Point& point)
{ {
// Do nothing // Do nothing
} }
void getPointsToInterwine(const std::vector<Point>& input, std::vector<Point>& output) void getPointsToInterwine(const Points& input, Points& output)
{ {
output = input; output = input;
} }
void getStatusBarText(const std::vector<Point>& points, std::string& text) void getStatusBarText(const Points& points, std::string& text)
{ {
char buf[1024]; char buf[1024];
sprintf(buf, "Pos %3d %3d", points[0].x, points[0].y); sprintf(buf, "Pos %3d %3d", points[0].x, points[0].y);
@ -222,11 +222,11 @@ public:
} }
}; };
class FourPointsController : public ToolController class FourPointsController : public Controller
{ {
int m_clickCounter; int m_clickCounter;
public: public:
void pressButton(std::vector<Point>& points, const Point& point) void pressButton(Points& points, const Point& point)
{ {
if (points.size() == 0) { if (points.size() == 0) {
points.resize(4, point); points.resize(4, point);
@ -235,12 +235,12 @@ public:
else else
m_clickCounter++; m_clickCounter++;
} }
bool releaseButton(std::vector<Point>& points, const Point& point) bool releaseButton(Points& points, const Point& point)
{ {
m_clickCounter++; m_clickCounter++;
return m_clickCounter < 4; return m_clickCounter < 4;
} }
void movement(IToolLoop* loop, std::vector<Point>& points, const Point& point) void movement(ToolLoop* loop, Points& points, const Point& point)
{ {
switch (m_clickCounter) { switch (m_clickCounter) {
case 0: case 0:
@ -257,11 +257,11 @@ public:
break; break;
} }
} }
void getPointsToInterwine(const std::vector<Point>& input, std::vector<Point>& output) void getPointsToInterwine(const Points& input, Points& output)
{ {
output = input; output = input;
} }
void getStatusBarText(const std::vector<Point>& points, std::string& text) void getStatusBarText(const Points& points, std::string& text)
{ {
char buf[1024]; char buf[1024];
sprintf(buf, "Start %3d %3d End %3d %3d (%3d %3d - %3d %3d)", sprintf(buf, "Start %3d %3d End %3d %3d (%3d %3d - %3d %3d)",

33
src/tools/fill.h Normal file
View File

@ -0,0 +1,33 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2011 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TOOLS_FILL_H_INCLUDED
#define TOOLS_FILL_H_INCLUDED
namespace tools {
enum Fill
{
FillNone,
FillAlways,
FillOptional,
};
} // namespace tools
#endif // TOOLS_FILL_H_INCLUDED

75
src/tools/ink.h Normal file
View File

@ -0,0 +1,75 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2011 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TOOLS_INK_H_INCLUDED
#define TOOLS_INK_H_INCLUDED
namespace tools {
class ToolLoop;
// Class used to paint directly in the destination image (loop->getDstImage())
//
// The main task of this class is to draw scanlines through its
// inkHline function member.
class Ink
{
// selection, paint, paint_fg, paint_bg, eraser,
// replace_fg_with_bg, replace_bg_with_fg, pick_fg, pick_bg, scroll,
// move, shade, blur, jumble
public:
virtual ~Ink() { }
// Returns true if this ink modifies the selection/mask
virtual bool isSelection() const { return false; }
// Returns true if this ink modifies the destination image
virtual bool isPaint() const { return false; }
// Returns true if this ink is an effect (is useful to know if a ink
// is a effect so the Editor can display the cursor bounds)
virtual bool isEffect() const { return false; }
// Returns true if this ink picks colors from the image
virtual bool isEyedropper() const { return false; }
// Returns true if this ink moves the scroll only
virtual bool isScrollMovement() const { return false; }
// Returns true if this ink moves cels
virtual bool isCelMovement() const { return false; }
// It is called when the tool-loop start (generally when the user
// presses a mouse button over a sprite editor)
virtual void prepareInk(ToolLoop* loop) { }
// It is used in the final stage of the tool-loop, it is called twice
// (first with state=true and then state=false)
virtual void setFinalStep(ToolLoop* loop, bool state) { }
// It is used to paint scanlines in the destination image.
// PointShapes call this method when they convert a mouse-point
// to a shape (e.g. pen shape) with various scanlines.
virtual void inkHline(int x1, int y, int x2, ToolLoop* loop) = 0;
};
} // namespace tools
#endif // TOOLS_INK_H_INCLUDED

View File

@ -83,7 +83,7 @@
// Opaque Ink // Opaque Ink
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
static void ink_hline32_opaque(int x1, int y, int x2, IToolLoop* loop) static void ink_hline32_opaque(int x1, int y, int x2, ToolLoop* loop)
{ {
int c = loop->getPrimaryColor(); int c = loop->getPrimaryColor();
@ -92,7 +92,7 @@ static void ink_hline32_opaque(int x1, int y, int x2, IToolLoop* loop)
*dst_address = c ); *dst_address = c );
} }
static void ink_hline16_opaque(int x1, int y, int x2, IToolLoop* loop) static void ink_hline16_opaque(int x1, int y, int x2, ToolLoop* loop)
{ {
int c = loop->getPrimaryColor(); int c = loop->getPrimaryColor();
@ -101,7 +101,7 @@ static void ink_hline16_opaque(int x1, int y, int x2, IToolLoop* loop)
*dst_address = c ); *dst_address = c );
} }
static void ink_hline8_opaque(int x1, int y, int x2, IToolLoop* loop) static void ink_hline8_opaque(int x1, int y, int x2, ToolLoop* loop)
{ {
int c = loop->getPrimaryColor(); int c = loop->getPrimaryColor();
@ -116,7 +116,7 @@ static void ink_hline8_opaque(int x1, int y, int x2, IToolLoop* loop)
// Transparent Ink // Transparent Ink
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
static void ink_hline32_transparent(int x1, int y, int x2, IToolLoop* loop) static void ink_hline32_transparent(int x1, int y, int x2, ToolLoop* loop)
{ {
int color = loop->getPrimaryColor(); int color = loop->getPrimaryColor();
int opacity = loop->getOpacity(); int opacity = loop->getOpacity();
@ -126,7 +126,7 @@ static void ink_hline32_transparent(int x1, int y, int x2, IToolLoop* loop)
*dst_address = _rgba_blend_normal(*src_address, color, opacity)); *dst_address = _rgba_blend_normal(*src_address, color, opacity));
} }
static void ink_hline16_transparent(int x1, int y, int x2, IToolLoop* loop) static void ink_hline16_transparent(int x1, int y, int x2, ToolLoop* loop)
{ {
int color = loop->getPrimaryColor(); int color = loop->getPrimaryColor();
int opacity = loop->getOpacity(); int opacity = loop->getOpacity();
@ -136,7 +136,7 @@ static void ink_hline16_transparent(int x1, int y, int x2, IToolLoop* loop)
*dst_address = _graya_blend_normal(*src_address, color, opacity)); *dst_address = _graya_blend_normal(*src_address, color, opacity));
} }
static void ink_hline8_transparent(int x1, int y, int x2, IToolLoop* loop) static void ink_hline8_transparent(int x1, int y, int x2, ToolLoop* loop)
{ {
Palette* pal = get_current_palette(); Palette* pal = get_current_palette();
RgbMap* rgbmap = loop->getSprite()->getRgbMap(); RgbMap* rgbmap = loop->getSprite()->getRgbMap();
@ -215,7 +215,7 @@ namespace {
}; };
}; };
static void ink_hline32_blur(int x1, int y, int x2, IToolLoop* loop) static void ink_hline32_blur(int x1, int y, int x2, ToolLoop* loop)
{ {
int opacity = loop->getOpacity(); int opacity = loop->getOpacity();
TiledMode tiledMode = loop->getTiledMode(); TiledMode tiledMode = loop->getTiledMode();
@ -248,7 +248,7 @@ static void ink_hline32_blur(int x1, int y, int x2, IToolLoop* loop)
}); });
} }
static void ink_hline16_blur(int x1, int y, int x2, IToolLoop* loop) static void ink_hline16_blur(int x1, int y, int x2, ToolLoop* loop)
{ {
int opacity = loop->getOpacity(); int opacity = loop->getOpacity();
TiledMode tiledMode = loop->getTiledMode(); TiledMode tiledMode = loop->getTiledMode();
@ -277,7 +277,7 @@ static void ink_hline16_blur(int x1, int y, int x2, IToolLoop* loop)
}); });
} }
static void ink_hline8_blur(int x1, int y, int x2, IToolLoop* loop) static void ink_hline8_blur(int x1, int y, int x2, ToolLoop* loop)
{ {
const Palette *pal = get_current_palette(); const Palette *pal = get_current_palette();
RgbMap* rgbmap = loop->getSprite()->getRgbMap(); RgbMap* rgbmap = loop->getSprite()->getRgbMap();
@ -314,7 +314,7 @@ static void ink_hline8_blur(int x1, int y, int x2, IToolLoop* loop)
// Replace Ink // Replace Ink
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
static void ink_hline32_replace(int x1, int y, int x2, IToolLoop* loop) static void ink_hline32_replace(int x1, int y, int x2, ToolLoop* loop)
{ {
uint32_t color1 = loop->getPrimaryColor(); uint32_t color1 = loop->getPrimaryColor();
uint32_t color2 = loop->getSecondaryColor(); uint32_t color2 = loop->getSecondaryColor();
@ -327,7 +327,7 @@ static void ink_hline32_replace(int x1, int y, int x2, IToolLoop* loop)
}); });
} }
static void ink_hline16_replace(int x1, int y, int x2, IToolLoop* loop) static void ink_hline16_replace(int x1, int y, int x2, ToolLoop* loop)
{ {
int color1 = loop->getPrimaryColor(); int color1 = loop->getPrimaryColor();
int color2 = loop->getSecondaryColor(); int color2 = loop->getSecondaryColor();
@ -340,7 +340,7 @@ static void ink_hline16_replace(int x1, int y, int x2, IToolLoop* loop)
}); });
} }
static void ink_hline8_replace(int x1, int y, int x2, IToolLoop* loop) static void ink_hline8_replace(int x1, int y, int x2, ToolLoop* loop)
{ {
int color1 = loop->getPrimaryColor(); int color1 = loop->getPrimaryColor();
const Palette *pal = get_current_palette(); const Palette *pal = get_current_palette();
@ -388,7 +388,7 @@ static void ink_hline8_replace(int x1, int y, int x2, IToolLoop* loop)
} \ } \
color = image_getpixel(loop->getSrcImage(), u, v); color = image_getpixel(loop->getSrcImage(), u, v);
static void ink_hline32_jumble(int x1, int y, int x2, IToolLoop* loop) static void ink_hline32_jumble(int x1, int y, int x2, ToolLoop* loop)
{ {
int opacity = loop->getOpacity(); int opacity = loop->getOpacity();
Point speed(loop->getSpeed() / 4); Point speed(loop->getSpeed() / 4);
@ -404,7 +404,7 @@ static void ink_hline32_jumble(int x1, int y, int x2, IToolLoop* loop)
); );
} }
static void ink_hline16_jumble(int x1, int y, int x2, IToolLoop* loop) static void ink_hline16_jumble(int x1, int y, int x2, ToolLoop* loop)
{ {
int opacity = loop->getOpacity(); int opacity = loop->getOpacity();
Point speed(loop->getSpeed() / 4); Point speed(loop->getSpeed() / 4);
@ -420,7 +420,7 @@ static void ink_hline16_jumble(int x1, int y, int x2, IToolLoop* loop)
); );
} }
static void ink_hline8_jumble(int x1, int y, int x2, IToolLoop* loop) static void ink_hline8_jumble(int x1, int y, int x2, ToolLoop* loop)
{ {
const Palette *pal = get_current_palette(); const Palette *pal = get_current_palette();
const RgbMap* rgbmap = loop->getSprite()->getRgbMap(); const RgbMap* rgbmap = loop->getSprite()->getRgbMap();

View File

@ -28,7 +28,7 @@
// Ink used for tools which paint with primary/secondary // Ink used for tools which paint with primary/secondary
// (or foreground/background colors) // (or foreground/background colors)
class PaintInk : public ToolInk class PaintInk : public Ink
{ {
public: public:
enum Type { Normal, WithFg, WithBg }; enum Type { Normal, WithFg, WithBg };
@ -42,7 +42,7 @@ public:
bool isPaint() const { return true; } bool isPaint() const { return true; }
void prepareInk(IToolLoop* loop) void prepareInk(ToolLoop* loop)
{ {
switch (m_type) { switch (m_type) {
@ -68,14 +68,14 @@ public:
ink_processing[INK_TRANSPARENT][MID(0, loop->getSprite()->getImgType(), 2)]; ink_processing[INK_TRANSPARENT][MID(0, loop->getSprite()->getImgType(), 2)];
} }
void inkHline(int x1, int y, int x2, IToolLoop* loop) void inkHline(int x1, int y, int x2, ToolLoop* loop)
{ {
(*m_proc)(x1, y, x2, loop); (*m_proc)(x1, y, x2, loop);
} }
}; };
class PickInk : public ToolInk class PickInk : public Ink
{ {
public: public:
enum Target { Fg, Bg }; enum Target { Fg, Bg };
@ -88,12 +88,12 @@ public:
bool isEyedropper() const { return true; } bool isEyedropper() const { return true; }
void prepareInk(IToolLoop* loop) void prepareInk(ToolLoop* loop)
{ {
// Do nothing // Do nothing
} }
void inkHline(int x1, int y, int x2, IToolLoop* loop) void inkHline(int x1, int y, int x2, ToolLoop* loop)
{ {
// Do nothing // Do nothing
} }
@ -101,18 +101,18 @@ public:
}; };
class ScrollInk : public ToolInk class ScrollInk : public Ink
{ {
public: public:
bool isScrollMovement() const { return true; } bool isScrollMovement() const { return true; }
void prepareInk(IToolLoop* loop) void prepareInk(ToolLoop* loop)
{ {
// Do nothing // Do nothing
} }
void inkHline(int x1, int y, int x2, IToolLoop* loop) void inkHline(int x1, int y, int x2, ToolLoop* loop)
{ {
// Do nothing // Do nothing
} }
@ -120,24 +120,24 @@ public:
}; };
class MoveInk : public ToolInk class MoveInk : public Ink
{ {
public: public:
bool isCelMovement() const { return true; } bool isCelMovement() const { return true; }
void prepareInk(IToolLoop* loop) void prepareInk(ToolLoop* loop)
{ {
// Do nothing // Do nothing
} }
void inkHline(int x1, int y, int x2, IToolLoop* loop) void inkHline(int x1, int y, int x2, ToolLoop* loop)
{ {
// Do nothing // Do nothing
} }
}; };
class EraserInk : public ToolInk class EraserInk : public Ink
{ {
public: public:
enum Type { Eraser, ReplaceFgWithBg, ReplaceBgWithFg }; enum Type { Eraser, ReplaceFgWithBg, ReplaceBgWithFg };
@ -152,7 +152,7 @@ public:
bool isPaint() const { return true; } bool isPaint() const { return true; }
bool isEffect() const { return true; } bool isEffect() const { return true; }
void prepareInk(IToolLoop* loop) void prepareInk(ToolLoop* loop)
{ {
switch (m_type) { switch (m_type) {
@ -184,14 +184,14 @@ public:
} }
} }
void inkHline(int x1, int y, int x2, IToolLoop* loop) void inkHline(int x1, int y, int x2, ToolLoop* loop)
{ {
(*m_proc)(x1, y, x2, loop); (*m_proc)(x1, y, x2, loop);
} }
}; };
class BlurInk : public ToolInk class BlurInk : public Ink
{ {
AlgoHLine m_proc; AlgoHLine m_proc;
@ -199,19 +199,19 @@ public:
bool isPaint() const { return true; } bool isPaint() const { return true; }
bool isEffect() const { return true; } bool isEffect() const { return true; }
void prepareInk(IToolLoop* loop) void prepareInk(ToolLoop* loop)
{ {
m_proc = ink_processing[INK_BLUR][MID(0, loop->getSprite()->getImgType(), 2)]; m_proc = ink_processing[INK_BLUR][MID(0, loop->getSprite()->getImgType(), 2)];
} }
void inkHline(int x1, int y, int x2, IToolLoop* loop) void inkHline(int x1, int y, int x2, ToolLoop* loop)
{ {
(*m_proc)(x1, y, x2, loop); (*m_proc)(x1, y, x2, loop);
} }
}; };
class JumbleInk : public ToolInk class JumbleInk : public Ink
{ {
AlgoHLine m_proc; AlgoHLine m_proc;
@ -219,12 +219,12 @@ public:
bool isPaint() const { return true; } bool isPaint() const { return true; }
bool isEffect() const { return true; } bool isEffect() const { return true; }
void prepareInk(IToolLoop* loop) void prepareInk(ToolLoop* loop)
{ {
m_proc = ink_processing[INK_JUMBLE][MID(0, loop->getSprite()->getImgType(), 2)]; m_proc = ink_processing[INK_JUMBLE][MID(0, loop->getSprite()->getImgType(), 2)];
} }
void inkHline(int x1, int y, int x2, IToolLoop* loop) void inkHline(int x1, int y, int x2, ToolLoop* loop)
{ {
(*m_proc)(x1, y, x2, loop); (*m_proc)(x1, y, x2, loop);
} }
@ -232,7 +232,7 @@ public:
// Ink used for selection tools (like Rectangle Marquee, Lasso, Magic Wand, etc.) // Ink used for selection tools (like Rectangle Marquee, Lasso, Magic Wand, etc.)
class SelectionInk : public ToolInk class SelectionInk : public Ink
{ {
bool m_modify_selection; bool m_modify_selection;
@ -241,7 +241,7 @@ public:
bool isSelection() const { return true; } bool isSelection() const { return true; }
void inkHline(int x1, int y, int x2, IToolLoop* loop) void inkHline(int x1, int y, int x2, ToolLoop* loop)
{ {
if (m_modify_selection) { if (m_modify_selection) {
Point offset = loop->getOffset(); Point offset = loop->getOffset();
@ -255,7 +255,7 @@ public:
image_hline(loop->getDstImage(), x1, y, x2, loop->getPrimaryColor()); image_hline(loop->getDstImage(), x1, y, x2, loop->getPrimaryColor());
} }
void setFinalStep(IToolLoop* loop, bool state) void setFinalStep(ToolLoop* loop, bool state)
{ {
m_modify_selection = state; m_modify_selection = state;

43
src/tools/intertwine.cpp Normal file
View File

@ -0,0 +1,43 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2011 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "tools/intertwine.h"
#include "raster/algo.h"
#include "tools/point_shape.h"
#include "tools/tool_loop.h"
using namespace gfx;
using namespace tools;
void Intertwine::doPointshapePoint(int x, int y, ToolLoop* loop)
{
loop->getPointShape()->transformPoint(loop, x, y);
}
void Intertwine::doPointshapeHline(int x1, int y, int x2, ToolLoop* loop)
{
algo_line(x1, y, x2, y, loop, (AlgoPixel)doPointshapePoint);
}
void Intertwine::doPointshapeLine(int x1, int y1, int x2, int y2, ToolLoop* loop)
{
algo_line(x1, y1, x2, y2, loop, (AlgoPixel)doPointshapePoint);
}

48
src/tools/intertwine.h Normal file
View File

@ -0,0 +1,48 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2011 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TOOLS_INTERTWINE_H_INCLUDED
#define TOOLS_INTERTWINE_H_INCLUDED
#include "gfx/point.h"
#include <vector>
namespace tools {
class ToolLoop;
class Intertwine
{
public:
typedef std::vector<gfx::Point> Points;
virtual ~Intertwine() { }
virtual bool snapByAngle() { return false; }
virtual void joinPoints(ToolLoop* loop, const Points& points) = 0;
virtual void fillPoints(ToolLoop* loop, const Points& points) = 0;
protected:
static void doPointshapePoint(int x, int y, ToolLoop* loop);
static void doPointshapeHline(int x1, int y, int x2, ToolLoop* loop);
static void doPointshapeLine(int x1, int y1, int x2, int y2, ToolLoop* loop);
};
} // namespace tools
#endif // TOOLS_INTERTWINE_H_INCLUDED

View File

@ -16,28 +16,28 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
class IntertwineNone : public ToolIntertwine class IntertwineNone : public Intertwine
{ {
public: public:
void joinPoints(IToolLoop* loop, const std::vector<Point>& points) void joinPoints(ToolLoop* loop, const Points& points)
{ {
for (size_t c=0; c<points.size(); ++c) for (size_t c=0; c<points.size(); ++c)
doPointshapePoint(points[c].x, points[c].y, loop); doPointshapePoint(points[c].x, points[c].y, loop);
} }
void fillPoints(IToolLoop* loop, const std::vector<Point>& points) void fillPoints(ToolLoop* loop, const Points& points)
{ {
joinPoints(loop, points); joinPoints(loop, points);
} }
}; };
class IntertwineAsLines : public ToolIntertwine class IntertwineAsLines : public Intertwine
{ {
public: public:
bool snapByAngle() { return true; } bool snapByAngle() { return true; }
void joinPoints(IToolLoop* loop, const std::vector<Point>& points) void joinPoints(ToolLoop* loop, const Points& points)
{ {
if (points.size() == 0) if (points.size() == 0)
return; return;
@ -64,7 +64,7 @@ public:
} }
} }
void fillPoints(IToolLoop* loop, const std::vector<Point>& points) void fillPoints(ToolLoop* loop, const Points& points)
{ {
if (points.size() < 3) { if (points.size() < 3) {
joinPoints(loop, points); joinPoints(loop, points);
@ -79,11 +79,11 @@ public:
} }
}; };
class IntertwineAsRectangles : public ToolIntertwine class IntertwineAsRectangles : public Intertwine
{ {
public: public:
void joinPoints(IToolLoop* loop, const std::vector<Point>& points) void joinPoints(ToolLoop* loop, const Points& points)
{ {
if (points.size() == 0) if (points.size() == 0)
return; return;
@ -113,7 +113,7 @@ public:
} }
} }
void fillPoints(IToolLoop* loop, const std::vector<Point>& points) void fillPoints(ToolLoop* loop, const Points& points)
{ {
if (points.size() < 2) { if (points.size() < 2) {
joinPoints(loop, points); joinPoints(loop, points);
@ -136,11 +136,11 @@ public:
} }
}; };
class IntertwineAsEllipses : public ToolIntertwine class IntertwineAsEllipses : public Intertwine
{ {
public: public:
void joinPoints(IToolLoop* loop, const std::vector<Point>& points) void joinPoints(ToolLoop* loop, const Points& points)
{ {
if (points.size() == 0) if (points.size() == 0)
return; return;
@ -163,7 +163,7 @@ public:
} }
} }
void fillPoints(IToolLoop* loop, const std::vector<Point>& points) void fillPoints(ToolLoop* loop, const Points& points)
{ {
if (points.size() < 2) { if (points.size() < 2) {
joinPoints(loop, points); joinPoints(loop, points);
@ -184,11 +184,11 @@ public:
} }
}; };
class IntertwineAsBezier : public ToolIntertwine class IntertwineAsBezier : public Intertwine
{ {
public: public:
void joinPoints(IToolLoop* loop, const std::vector<Point>& points) void joinPoints(ToolLoop* loop, const Points& points)
{ {
if (points.size() == 0) if (points.size() == 0)
return; return;
@ -216,7 +216,7 @@ public:
} }
} }
void fillPoints(IToolLoop* loop, const std::vector<Point>& points) void fillPoints(ToolLoop* loop, const Points& points)
{ {
joinPoints(loop, points); joinPoints(loop, points);
} }

82
src/tools/point_shape.cpp Normal file
View File

@ -0,0 +1,82 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2011 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "tools/point_shape.h"
#include "raster/image.h"
#include "tools/ink.h"
#include "tools/tool_loop.h"
using namespace tools;
void PointShape::doInkHline(int x1, int y, int x2, ToolLoop* loop)
{
register int w, size; // width or height
register int x;
// Tiled in Y axis
if (loop->getTiledMode() & TILED_Y_AXIS) {
size = loop->getDstImage()->h; // size = image height
if (y < 0)
y = size - (-(y+1) % size) - 1;
else
y = y % size;
}
else if (y < 0 || y >= loop->getDstImage()->h)
return;
// Tiled in X axis
if (loop->getTiledMode() & TILED_X_AXIS) {
if (x1 > x2)
return;
size = loop->getDstImage()->w; // size = image width
w = x2-x1+1;
if (w >= size)
loop->getInk()->inkHline(0, y, size-1, loop);
else {
x = x1;
if (x < 0)
x = size - (-(x+1) % size) - 1;
else
x = x % size;
if (x+w-1 <= size-1)
loop->getInk()->inkHline(x, y, x+w-1, loop);
else {
loop->getInk()->inkHline(x, y, size-1, loop);
loop->getInk()->inkHline(0, y, w-(size-x)-1, loop);
}
}
}
// Clipped in X axis
else {
if (x1 < 0)
x1 = 0;
if (x2 >= loop->getDstImage()->w)
x2 = loop->getDstImage()->w-1;
if (x2-x1+1 < 1)
return;
loop->getInk()->inkHline(x1, y, x2, loop);
}
}

47
src/tools/point_shape.h Normal file
View File

@ -0,0 +1,47 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2011 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TOOLS_TOOL_POINT_SHAPE_INCLUDED
#define TOOLS_TOOL_POINT_SHAPE_H_INCLUDED
#include "gfx/rect.h"
namespace tools {
class ToolLoop;
// Converts a point to a shape to be drawn
class PointShape
{
public:
virtual ~PointShape() { }
virtual bool isFloodFill() { return false; }
virtual bool isSpray() { return false; }
virtual void transformPoint(ToolLoop* loop, int x, int y) = 0;
virtual void getModifiedArea(ToolLoop* loop, int x, int y, gfx::Rect& area) = 0;
protected:
// Calls loop->getInk()->inkHline() function for each horizontal-scanline
// that should be drawn (applying the "tiled" mode loop->getTiledMode())
static void doInkHline(int x1, int y, int x2, ToolLoop* loop);
};
} // namespace tools
#endif // TOOLS_INK_H_INCLUDED

View File

@ -16,36 +16,36 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
class NonePointShape : public ToolPointShape class NonePointShape : public PointShape
{ {
public: public:
void transformPoint(IToolLoop* loop, int x, int y) void transformPoint(ToolLoop* loop, int x, int y)
{ {
// Do nothing // Do nothing
} }
void getModifiedArea(IToolLoop* loop, int x, int y, Rect& area) void getModifiedArea(ToolLoop* loop, int x, int y, Rect& area)
{ {
// Do nothing // Do nothing
} }
}; };
class PixelPointShape : public ToolPointShape class PixelPointShape : public PointShape
{ {
public: public:
void transformPoint(IToolLoop* loop, int x, int y) void transformPoint(ToolLoop* loop, int x, int y)
{ {
doInkHline(x, y, x, loop); doInkHline(x, y, x, loop);
} }
void getModifiedArea(IToolLoop* loop, int x, int y, Rect& area) void getModifiedArea(ToolLoop* loop, int x, int y, Rect& area)
{ {
area = Rect(x, y, 1, 1); area = Rect(x, y, 1, 1);
} }
}; };
class PenPointShape : public ToolPointShape class PenPointShape : public PointShape
{ {
public: public:
void transformPoint(IToolLoop* loop, int x, int y) void transformPoint(ToolLoop* loop, int x, int y)
{ {
Pen* pen = loop->getPen(); Pen* pen = loop->getPen();
std::vector<PenScanline>::const_iterator scanline = pen->get_scanline().begin(); std::vector<PenScanline>::const_iterator scanline = pen->get_scanline().begin();
@ -61,7 +61,7 @@ public:
++scanline; ++scanline;
} }
} }
void getModifiedArea(IToolLoop* loop, int x, int y, Rect& area) void getModifiedArea(ToolLoop* loop, int x, int y, Rect& area)
{ {
Pen* pen = loop->getPen(); Pen* pen = loop->getPen();
int size = pen->get_size(); int size = pen->get_size();
@ -69,22 +69,22 @@ public:
} }
}; };
class FloodFillPointShape : public ToolPointShape class FloodFillPointShape : public PointShape
{ {
public: public:
bool isFloodFill() { return true; } bool isFloodFill() { return true; }
void transformPoint(IToolLoop* loop, int x, int y) void transformPoint(ToolLoop* loop, int x, int y)
{ {
algo_floodfill(loop->getSrcImage(), x, y, loop->getTolerance(), loop, (AlgoHLine)doInkHline); algo_floodfill(loop->getSrcImage(), x, y, loop->getTolerance(), loop, (AlgoHLine)doInkHline);
} }
void getModifiedArea(IToolLoop* loop, int x, int y, Rect& area) void getModifiedArea(ToolLoop* loop, int x, int y, Rect& area)
{ {
area = Rect(0, 0, 9999, 9999); area = Rect(0, 0, 9999, 9999);
} }
}; };
class SprayPointShape : public ToolPointShape class SprayPointShape : public PointShape
{ {
PenPointShape m_subPointShape; PenPointShape m_subPointShape;
@ -92,7 +92,7 @@ public:
bool isSpray() { return true; } bool isSpray() { return true; }
void transformPoint(IToolLoop* loop, int x, int y) void transformPoint(ToolLoop* loop, int x, int y)
{ {
int spray_width = loop->getSprayWidth(); int spray_width = loop->getSprayWidth();
int spray_speed = loop->getSpraySpeed(); int spray_speed = loop->getSpraySpeed();
@ -123,7 +123,7 @@ public:
#endif #endif
} }
void getModifiedArea(IToolLoop* loop, int x, int y, Rect& area) void getModifiedArea(ToolLoop* loop, int x, int y, Rect& area)
{ {
int spray_width = loop->getSprayWidth(); int spray_width = loop->getSprayWidth();
Point p1(x-spray_width, y-spray_width); Point p1(x-spray_width, y-spray_width);

View File

@ -19,163 +19,22 @@
#ifndef TOOLS_TOOL_H_INCLUDED #ifndef TOOLS_TOOL_H_INCLUDED
#define TOOLS_TOOL_H_INCLUDED #define TOOLS_TOOL_H_INCLUDED
#include <list>
#include <string> #include <string>
#include <vector>
#include "filters/tiled_mode.h" #include "tools/fill.h"
#include "gfx/point.h" #include "tools/trace_policy.h"
#include "gfx/rect.h"
class Context; namespace tools {
class Document;
class Image;
class Layer;
class Mask;
class Pen;
class Sprite;
class Tool;
class IToolLoop; class Controller;
class Ink;
enum ToolFill class Intertwine;
{ class PointShape;
TOOL_FILL_NONE, class ToolGroup;
TOOL_FILL_ALWAYS,
TOOL_FILL_OPTIONAL,
};
enum ToolTracePolicy
{
TOOL_TRACE_POLICY_ACCUMULATE,
TOOL_TRACE_POLICY_LAST,
TOOL_TRACE_POLICY_OVERLAP,
};
// Class used to paint directly in the destination image (loop->getDstImage())
//
// The main task of this class is to draw scanlines through its
// inkHline function member.
class ToolInk
{
// selection, paint, paint_fg, paint_bg, eraser,
// replace_fg_with_bg, replace_bg_with_fg, pick_fg, pick_bg, scroll,
// move, shade, blur, jumble
public:
virtual ~ToolInk() { }
// Returns true if this ink modifies the selection/mask
virtual bool isSelection() const { return false; }
// Returns true if this ink modifies the destination image
virtual bool isPaint() const { return false; }
// Returns true if this ink is an effect (is useful to know if a ink
// is a effect so the Editor can display the cursor bounds)
virtual bool isEffect() const { return false; }
// Returns true if this ink picks colors from the image
virtual bool isEyedropper() const { return false; }
// Returns true if this ink moves the scroll only
virtual bool isScrollMovement() const { return false; }
// Returns true if this ink moves cels
virtual bool isCelMovement() const { return false; }
// It is called when the tool-loop start (generally when the user
// presses a mouse button over a sprite editor)
virtual void prepareInk(IToolLoop* loop) { }
// It is used in the final stage of the tool-loop, it is called twice
// (first with state=true and then state=false)
virtual void setFinalStep(IToolLoop* loop, bool state) { }
// It is used to paint scanlines in the destination image.
// ToolPointShapes call this method when they convert a mouse-point
// to a shape (e.g. pen shape) with various scanlines.
virtual void inkHline(int x1, int y, int x2, IToolLoop* loop) = 0;
};
// This class controls user input.
class ToolController
{
// freehand, point_by_point, one_point, two_points, four_points
public:
virtual ~ToolController() { }
virtual bool canSnapToGrid() { return true; }
virtual void pressButton(std::vector<gfx::Point>& points, const gfx::Point& point) = 0;
virtual bool releaseButton(std::vector<gfx::Point>& points, const gfx::Point& point) = 0;
virtual void movement(IToolLoop* loop, std::vector<gfx::Point>& points, const gfx::Point& point) = 0;
virtual void getPointsToInterwine(const std::vector<gfx::Point>& input, std::vector<gfx::Point>& output) = 0;
virtual void getStatusBarText(const std::vector<gfx::Point>& points, std::string& text) = 0;
};
// Converts a point to a shape to be drawn
class ToolPointShape
{
// none, pixel, pen, floodfill, spray
public:
virtual ~ToolPointShape() { }
virtual bool isFloodFill() { return false; }
virtual bool isSpray() { return false; }
virtual void transformPoint(IToolLoop* loop, int x, int y) = 0;
virtual void getModifiedArea(IToolLoop* loop, int x, int y, gfx::Rect& area) = 0;
protected:
// Calls loop->getInk()->inkHline() function for each horizontal-scanline
// that should be drawn (applying the "tiled" mode loop->getTiledMode())
static void doInkHline(int x1, int y, int x2, IToolLoop* loop);
};
class ToolIntertwine
{
// none, as_lines, as_bezier, as_rectangles, as_ellipses
public:
virtual ~ToolIntertwine() { }
virtual bool snapByAngle() { return false; }
virtual void joinPoints(IToolLoop* loop, const std::vector<gfx::Point>& points) = 0;
virtual void fillPoints(IToolLoop* loop, const std::vector<gfx::Point>& points) = 0;
protected:
static void doPointshapePoint(int x, int y, IToolLoop* loop);
static void doPointshapeHline(int x1, int y, int x2, IToolLoop* loop);
static void doPointshapeLine(int x1, int y1, int x2, int y2, IToolLoop* loop);
};
// A group of tools.
class ToolGroup
{
std::string m_name;
std::string m_label;
public:
ToolGroup(const char* name,
const char* label) : m_name(name)
, m_label(label) { }
const std::string& getName() const { return m_name; }
const std::string& getLabel() const { return m_label; }
};
// A drawing tool // A drawing tool
class Tool class Tool
{ {
ToolGroup* m_group;
std::string m_id;
std::string m_text;
std::string m_tips;
int m_default_pen_size;
struct {
ToolFill m_fill;
ToolInk* m_ink;
ToolController* m_controller;
ToolPointShape* m_point_shape;
ToolIntertwine* m_intertwine;
ToolTracePolicy m_trace_policy;
} m_button[2]; // Two buttons: [0] left and [1] right
public: public:
Tool(ToolGroup* group, Tool(ToolGroup* group,
@ -199,223 +58,39 @@ public:
const std::string& getTips() const { return m_tips; } const std::string& getTips() const { return m_tips; }
int getDefaultPenSize() const { return m_default_pen_size; } int getDefaultPenSize() const { return m_default_pen_size; }
ToolFill getFill(int button) { return m_button[button].m_fill; } Fill getFill(int button) { return m_button[button].m_fill; }
ToolInk* getInk(int button) { return m_button[button].m_ink; } Ink* getInk(int button) { return m_button[button].m_ink; }
ToolController* getController(int button) { return m_button[button].m_controller; } Controller* getController(int button) { return m_button[button].m_controller; }
ToolPointShape* getPointShape(int button) { return m_button[button].m_point_shape; } PointShape* getPointShape(int button) { return m_button[button].m_point_shape; }
ToolIntertwine* getIntertwine(int button) { return m_button[button].m_intertwine; } Intertwine* getIntertwine(int button) { return m_button[button].m_intertwine; }
ToolTracePolicy getTracePolicy(int button) { return m_button[button].m_trace_policy; } TracePolicy getTracePolicy(int button) { return m_button[button].m_trace_policy; }
void setFill(int button, ToolFill fill) { m_button[button].m_fill = fill; } void setFill(int button, Fill fill) { m_button[button].m_fill = fill; }
void setInk(int button, ToolInk* ink) { m_button[button].m_ink = ink; } void setInk(int button, Ink* ink) { m_button[button].m_ink = ink; }
void setController(int button, ToolController* controller) { m_button[button].m_controller = controller; } void setController(int button, Controller* controller) { m_button[button].m_controller = controller; }
void setPointShape(int button, ToolPointShape* point_shape) { m_button[button].m_point_shape = point_shape; } void setPointShape(int button, PointShape* point_shape) { m_button[button].m_point_shape = point_shape; }
void setIntertwine(int button, ToolIntertwine* intertwine) { m_button[button].m_intertwine = intertwine; } void setIntertwine(int button, Intertwine* intertwine) { m_button[button].m_intertwine = intertwine; }
void setTracePolicy(int button, ToolTracePolicy trace_policy) { m_button[button].m_trace_policy = trace_policy; } void setTracePolicy(int button, TracePolicy trace_policy) { m_button[button].m_trace_policy = trace_policy; }
};
// Interface to communicate the sprite editor with the tool when the user
// start using a tool to paint, select, pick color, etc.
//
// All this information should be provided by the editor and consumed
// by the tool (+controller+intertwiner+pointshape+ink).
class IToolLoop
{
public:
virtual ~IToolLoop() { }
// Returns the context where we want to draw on (generally UIContext::instance() singleton)
virtual Context* getContext() = 0;
// Returns the tool to use to draw or use
virtual Tool* getTool() = 0;
// Returns the pen which will be used with the tool
virtual Pen* getPen() = 0;
// Returns the document to which belongs the sprite.
virtual Document* getDocument() = 0;
// Returns the sprite where we will draw on
virtual Sprite* getSprite() = 0;
// Returns the layer that will be modified if the tool paints
virtual Layer* getLayer() = 0;
// Should return an image where we can read pixels (readonly image)
virtual Image* getSrcImage() = 0;
// Should return an image where we can write pixels
virtual Image* getDstImage() = 0;
// Returns true if we should use the mask to limit the paint area.
virtual bool useMask() = 0;
// Current mask to limit paint area
virtual Mask* getMask() = 0;
// Gets mask X,Y origin coordinates
virtual gfx::Point getMaskOrigin() = 0;
// Return the mouse button which start the tool-loop (0 = left
// button, 1 = right button). It can be used by some tools that
// instead of using the primary/secondary color uses the pressed
// button for different behavior (like selection tools)
virtual int getMouseButton() = 0;
// Primary color to draw (e.g. foreground if the user start drawing
// with the left button, or background color if he used the right
// button)
virtual int getPrimaryColor() = 0;
virtual void setPrimaryColor(int color) = 0;
// Secondary color to draw (e.g. background if the user start drawing
// with the left button, or foreground color if he used the right
// button)
virtual int getSecondaryColor() = 0;
virtual void setSecondaryColor(int color) = 0;
// Returns the opacity to be used by the ink (ToolInk).
virtual int getOpacity() = 0;
// Returns the tolerance to be used by the ink (ToolInk).
virtual int getTolerance() = 0;
// Returns true if each scanline generated by a ToolPointShape must
// be "tiled". See the method ToolPointShape::doInkHline to check
// how this member is used. When tiled mode is activated, each
// scanline can be divided in various sub-lines if they pass the
// image bounds. For each of these scanlines a ToolInk::inkHline
// is called
virtual TiledMode getTiledMode() = 0;
// Returns true if the figure must be filled when we release the
// mouse (e.g. a filled rectangle, etc.)
//
// To fill a shape, the ToolIntertwine::fillPoints function is used.
virtual bool getFilled() = 0;
// Returns true if the preview should be with filled shapes.
virtual bool getPreviewFilled() = 0;
// Spray configuration
virtual int getSprayWidth() = 0;
virtual int getSpraySpeed() = 0;
// Offset for each point
virtual gfx::Point getOffset() = 0;
// Velocity vector of the mouse
virtual void setSpeed(const gfx::Point& speed) = 0;
virtual gfx::Point getSpeed() = 0;
// Returns the ink to use with the tool. Each tool has an associated
// ink, but it could be modified for this specific loop, so
// generally you should return the same ink as the tool, but it can
// be different. The same for the other properties.
virtual ToolInk* getInk() = 0;
virtual ToolController* getController() = 0;
virtual ToolPointShape* getPointShape() = 0;
virtual ToolIntertwine* getIntertwine() = 0;
virtual ToolTracePolicy getTracePolicy() = 0;
// Used by the tool when the user cancels the operation pressing the
// other mouse button.
virtual void cancel() = 0;
// Returns true if the loop was canceled by the user
virtual bool isCanceled() = 0;
// Converts a coordinate in the screen to the sprite.
virtual gfx::Point screenToSprite(const gfx::Point& screenPoint) = 0;
// Redraws in the screen the specified are of sprite.
virtual void updateArea(const gfx::Rect& dirty_area) = 0;
virtual void updateStatusBar(const char* text) = 0;
};
// Class to manage the drawing tool (editor <-> tool interface).
//
// The flow is this:
// 1. The user press a mouse button in a Editor widget
// 2. The Editor creates an implementation of IToolLoop and use it
// with the ToolLoopManager constructor
// 3. The ToolLoopManager is used to call
// the following methods:
// - ToolLoopManager::prepareLoop
// - ToolLoopManager::pressButton
// 4. If the user moves the mouse, the method
// - ToolLoopManager::movement
// is called.
// 5. When the user release the mouse:
// - ToolLoopManager::releaseButton
// - ToolLoopManager::releaseLoop
class ToolLoopManager
{
IToolLoop* m_toolLoop;
std::vector<gfx::Point> m_points;
gfx::Point m_oldPoint;
public:
// Simple container of mouse events information.
class Pointer
{
public:
enum Button { Left, Middle, Right };
Pointer(int x, int y, Button button)
: m_x(x), m_y(y), m_button(button) { }
int getX() const { return m_x; }
int getY() const { return m_y; }
Button getButton() const { return m_button; }
private:
int m_x, m_y;
Button m_button;
};
// Contructs a manager for the IToolLoop delegate.
ToolLoopManager(IToolLoop* toolLoop);
virtual ~ToolLoopManager();
bool isCanceled() const { return m_toolLoop->isCanceled(); }
// Should be called when the user start a tool-trace (pressing the
// left or right button for first time in the editor).
void prepareLoop(const Pointer& pointer);
// Called when the loop is over.
void releaseLoop(const Pointer& pointer);
// Should be called each time the user presses a mouse button.
void pressButton(const Pointer& pointer);
// Should be called each time the user releases a mouse button.
//
// Returns true if the tool-loop should continue, or false
// if the editor should release the mouse capture.
bool releaseButton(const Pointer& pointer);
// Should be called each time the user moves the mouse inside the editor.
void movement(const Pointer& pointer);
private: private:
void doLoopStep(bool last_step); ToolGroup* m_group;
void snapToGrid(bool flexible, gfx::Point& point); std::string m_id;
std::string m_text;
std::string m_tips;
int m_default_pen_size;
static void calculateDirtyArea(IToolLoop* loop, struct {
const std::vector<gfx::Point>& points, Fill m_fill;
gfx::Rect& dirty_area); Ink* m_ink;
Controller* m_controller;
PointShape* m_point_shape;
Intertwine* m_intertwine;
TracePolicy m_trace_policy;
} m_button[2]; // Two buttons: [0] left and [1] right
static void calculateMinMax(const std::vector<gfx::Point>& points,
gfx::Point& minpt,
gfx::Point& maxpt);
}; };
#endif } // namespace tools
#endif // TOOLS_TOOL_H_INCLUDED

View File

@ -18,21 +18,27 @@
#include "config.h" #include "config.h"
#include <algorithm>
#include <allegro/file.h>
#include <allegro/fixed.h>
#include <allegro/fmaths.h>
#include "base/exception.h" #include "base/exception.h"
#include "gui_xml.h" #include "gui_xml.h"
#include "raster/algo.h" #include "raster/algo.h"
#include "raster/image.h" #include "raster/image.h"
#include "raster/mask.h" #include "raster/mask.h"
#include "raster/pen.h" #include "raster/pen.h"
#include "raster/sprite.h" #include "tools/controller.h"
#include "tools/toolbox.h" #include "tools/ink.h"
#include "tools/intertwine.h"
#include "tools/point_shape.h"
#include "tools/tool_box.h"
#include "tools/tool_group.h"
#include "tools/tool_loop.h"
#include <algorithm>
#include <allegro/file.h>
#include <allegro/fixed.h>
#include <allegro/fmaths.h>
using namespace gfx; using namespace gfx;
using namespace tools;
#include "tools/controllers.h" #include "tools/controllers.h"
#include "tools/inks.h" #include "tools/inks.h"
@ -181,51 +187,51 @@ void ToolBox::loadToolProperties(TiXmlElement* xmlTool, Tool* tool, int button,
if (!tracepolicy) tracepolicy = xmlTool->Attribute("tracepolicy"); if (!tracepolicy) tracepolicy = xmlTool->Attribute("tracepolicy");
// Fill // Fill
ToolFill fill_value = TOOL_FILL_NONE; Fill fill_value = FillNone;
if (fill) { if (fill) {
if (strcmp(fill, "none") == 0) if (strcmp(fill, "none") == 0)
fill_value = TOOL_FILL_NONE; fill_value = FillNone;
else if (strcmp(fill, "always") == 0) else if (strcmp(fill, "always") == 0)
fill_value = TOOL_FILL_ALWAYS; fill_value = FillAlways;
else if (strcmp(fill, "optional") == 0) else if (strcmp(fill, "optional") == 0)
fill_value = TOOL_FILL_OPTIONAL; fill_value = FillOptional;
else else
throw base::Exception("Invalid fill '%s' specified in '%s' tool.\n", fill, tool_id); throw base::Exception("Invalid fill '%s' specified in '%s' tool.\n", fill, tool_id);
} }
// Find the ink // Find the ink
std::map<std::string, ToolInk*>::iterator it_ink std::map<std::string, Ink*>::iterator it_ink
= m_inks.find(ink ? ink: ""); = m_inks.find(ink ? ink: "");
if (it_ink == m_inks.end()) if (it_ink == m_inks.end())
throw base::Exception("Invalid ink '%s' specified in '%s' tool.\n", ink, tool_id); throw base::Exception("Invalid ink '%s' specified in '%s' tool.\n", ink, tool_id);
// Find the controller // Find the controller
std::map<std::string, ToolController*>::iterator it_controller std::map<std::string, Controller*>::iterator it_controller
= m_controllers.find(controller ? controller: "none"); = m_controllers.find(controller ? controller: "none");
if (it_controller == m_controllers.end()) if (it_controller == m_controllers.end())
throw base::Exception("Invalid controller '%s' specified in '%s' tool.\n", controller, tool_id); throw base::Exception("Invalid controller '%s' specified in '%s' tool.\n", controller, tool_id);
// Find the point_shape // Find the point_shape
std::map<std::string, ToolPointShape*>::iterator it_pointshaper std::map<std::string, PointShape*>::iterator it_pointshaper
= m_pointshapers.find(pointshape ? pointshape: "none"); = m_pointshapers.find(pointshape ? pointshape: "none");
if (it_pointshaper == m_pointshapers.end()) if (it_pointshaper == m_pointshapers.end())
throw base::Exception("Invalid point-shape '%s' specified in '%s' tool.\n", pointshape, tool_id); throw base::Exception("Invalid point-shape '%s' specified in '%s' tool.\n", pointshape, tool_id);
// Find the intertwiner // Find the intertwiner
std::map<std::string, ToolIntertwine*>::iterator it_intertwiner std::map<std::string, Intertwine*>::iterator it_intertwiner
= m_intertwiners.find(intertwine ? intertwine: "none"); = m_intertwiners.find(intertwine ? intertwine: "none");
if (it_intertwiner == m_intertwiners.end()) if (it_intertwiner == m_intertwiners.end())
throw base::Exception("Invalid intertwiner '%s' specified in '%s' tool.\n", intertwine, tool_id); throw base::Exception("Invalid intertwiner '%s' specified in '%s' tool.\n", intertwine, tool_id);
// Trace policy // Trace policy
ToolTracePolicy tracepolicy_value = TOOL_TRACE_POLICY_LAST; TracePolicy tracepolicy_value = TracePolicyLast;
if (tracepolicy) { if (tracepolicy) {
if (strcmp(tracepolicy, "accumulative") == 0) if (strcmp(tracepolicy, "accumulative") == 0)
tracepolicy_value = TOOL_TRACE_POLICY_ACCUMULATE; tracepolicy_value = TracePolicyAccumulate;
else if (strcmp(tracepolicy, "last") == 0) else if (strcmp(tracepolicy, "last") == 0)
tracepolicy_value = TOOL_TRACE_POLICY_LAST; tracepolicy_value = TracePolicyLast;
else if (strcmp(tracepolicy, "overlap") == 0) else if (strcmp(tracepolicy, "overlap") == 0)
tracepolicy_value = TOOL_TRACE_POLICY_OVERLAP; tracepolicy_value = TracePolicyOverlap;
else else
throw base::Exception("Invalid trace-policy '%s' specified in '%s' tool.\n", tracepolicy, tool_id); throw base::Exception("Invalid trace-policy '%s' specified in '%s' tool.\n", tracepolicy, tool_id);
} }

View File

@ -16,16 +16,19 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifndef TOOLS_TOOLBOX_H_INCLUDED #ifndef TOOLS_TOOL_BOX_H_INCLUDED
#define TOOLS_TOOLBOX_H_INCLUDED #define TOOLS_TOOL_BOX_H_INCLUDED
#include <string> #include <string>
#include <list> #include <list>
#include <map> #include <map>
#include "tools/tool.h" #include "tools/tool.h"
class TiXmlElement; class TiXmlElement;
namespace tools {
typedef std::list<Tool*> ToolList; typedef std::list<Tool*> ToolList;
typedef ToolList::iterator ToolIterator; typedef ToolList::iterator ToolIterator;
typedef ToolList::const_iterator ToolConstIterator; typedef ToolList::const_iterator ToolConstIterator;
@ -35,14 +38,6 @@ typedef std::list<ToolGroup*> ToolGroupList;
// Loads and maintains the group of tools specified in the gui.xml file // Loads and maintains the group of tools specified in the gui.xml file
class ToolBox class ToolBox
{ {
std::map<std::string, ToolInk*> m_inks;
std::map<std::string, ToolController*> m_controllers;
std::map<std::string, ToolPointShape*> m_pointshapers;
std::map<std::string, ToolIntertwine*> m_intertwiners;
ToolGroupList m_groups;
ToolList m_tools;
public: public:
ToolBox(); ToolBox();
~ToolBox(); ~ToolBox();
@ -61,8 +56,17 @@ public:
private: private:
void loadTools(); void loadTools();
void loadToolProperties(TiXmlElement* xmlTool, Tool* tool, int button, const std::string& suffix); void loadToolProperties(TiXmlElement* xmlTool, Tool* tool, int button, const std::string& suffix);
std::map<std::string, Ink*> m_inks;
std::map<std::string, Controller*> m_controllers;
std::map<std::string, PointShape*> m_pointshapers;
std::map<std::string, Intertwine*> m_intertwiners;
ToolGroupList m_groups;
ToolList m_tools;
}; };
#endif } // namespace tools
#endif // TOOLS_TOOL_BOX_H_INCLUDED

45
src/tools/tool_group.h Normal file
View File

@ -0,0 +1,45 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2011 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TOOLS_TOOL_GROUP_H_INCLUDED
#define TOOLS_TOOL_GROUP_H_INCLUDED
#include <string>
namespace tools {
// A group of tools.
class ToolGroup
{
public:
ToolGroup(const char* name,
const char* label) : m_name(name)
, m_label(label) { }
const std::string& getName() const { return m_name; }
const std::string& getLabel() const { return m_label; }
private:
std::string m_name;
std::string m_label;
};
} // namespace tools
#endif // TOOLS_TOOL_GROUP_H_INCLUDED

168
src/tools/tool_loop.h Normal file
View File

@ -0,0 +1,168 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2011 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TOOLS_TOOL_LOOP_H_INCLUDED
#define TOOLS_TOOL_LOOP_H_INCLUDED
#include "filters/tiled_mode.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "tools/trace_policy.h"
class Context;
class Document;
class Image;
class Layer;
class Mask;
class Pen;
class Sprite;
namespace tools {
class Controller;
class Ink;
class Intertwine;
class PointShape;
class Tool;
// Interface to communicate the sprite editor with the tool when the user
// start using a tool to paint, select, pick color, etc.
//
// All this information should be provided by the editor and consumed
// by the tool (+controller+intertwiner+pointshape+ink).
class ToolLoop
{
public:
virtual ~ToolLoop() { }
// Returns the context where we want to draw on (generally UIContext::instance() singleton)
virtual Context* getContext() = 0;
// Returns the tool to use to draw or use
virtual Tool* getTool() = 0;
// Returns the pen which will be used with the tool
virtual Pen* getPen() = 0;
// Returns the document to which belongs the sprite.
virtual Document* getDocument() = 0;
// Returns the sprite where we will draw on
virtual Sprite* getSprite() = 0;
// Returns the layer that will be modified if the tool paints
virtual Layer* getLayer() = 0;
// Should return an image where we can read pixels (readonly image)
virtual Image* getSrcImage() = 0;
// Should return an image where we can write pixels
virtual Image* getDstImage() = 0;
// Returns true if we should use the mask to limit the paint area.
virtual bool useMask() = 0;
// Current mask to limit paint area
virtual Mask* getMask() = 0;
// Gets mask X,Y origin coordinates
virtual gfx::Point getMaskOrigin() = 0;
// Return the mouse button which start the tool-loop (0 = left
// button, 1 = right button). It can be used by some tools that
// instead of using the primary/secondary color uses the pressed
// button for different behavior (like selection tools)
virtual int getMouseButton() = 0;
// Primary color to draw (e.g. foreground if the user start drawing
// with the left button, or background color if he used the right
// button)
virtual int getPrimaryColor() = 0;
virtual void setPrimaryColor(int color) = 0;
// Secondary color to draw (e.g. background if the user start drawing
// with the left button, or foreground color if he used the right
// button)
virtual int getSecondaryColor() = 0;
virtual void setSecondaryColor(int color) = 0;
// Returns the opacity to be used by the ink (Ink).
virtual int getOpacity() = 0;
// Returns the tolerance to be used by the ink (Ink).
virtual int getTolerance() = 0;
// Returns true if each scanline generated by a PointShape must
// be "tiled". See the method PointShape::doInkHline to check
// how this member is used. When tiled mode is activated, each
// scanline can be divided in various sub-lines if they pass the
// image bounds. For each of these scanlines a Ink::inkHline
// is called
virtual TiledMode getTiledMode() = 0;
// Returns true if the figure must be filled when we release the
// mouse (e.g. a filled rectangle, etc.)
//
// To fill a shape, the Intertwine::fillPoints function is used.
virtual bool getFilled() = 0;
// Returns true if the preview should be with filled shapes.
virtual bool getPreviewFilled() = 0;
// Spray configuration
virtual int getSprayWidth() = 0;
virtual int getSpraySpeed() = 0;
// Offset for each point
virtual gfx::Point getOffset() = 0;
// Velocity vector of the mouse
virtual void setSpeed(const gfx::Point& speed) = 0;
virtual gfx::Point getSpeed() = 0;
// Returns the ink to use with the tool. Each tool has an associated
// ink, but it could be modified for this specific loop, so
// generally you should return the same ink as the tool, but it can
// be different. The same for the other properties.
virtual Ink* getInk() = 0;
virtual Controller* getController() = 0;
virtual PointShape* getPointShape() = 0;
virtual Intertwine* getIntertwine() = 0;
virtual TracePolicy getTracePolicy() = 0;
// Used by the tool when the user cancels the operation pressing the
// other mouse button.
virtual void cancel() = 0;
// Returns true if the loop was canceled by the user
virtual bool isCanceled() = 0;
// Converts a coordinate in the screen to the sprite.
virtual gfx::Point screenToSprite(const gfx::Point& screenPoint) = 0;
// Redraws in the screen the specified are of sprite.
virtual void updateArea(const gfx::Rect& dirty_area) = 0;
virtual void updateStatusBar(const char* text) = 0;
};
} // namespace tools
#endif // TOOLS_TOOL_LOOP_H_INCLUDED

View File

@ -18,94 +18,21 @@
#include "config.h" #include "config.h"
#include "raster/algo.h" #include "tools/tool_loop_manager.h"
#include "raster/image.h"
#include "tools/tool.h"
#include "util/render.h"
#include "context.h" #include "context.h"
#include "raster/image.h"
#include "tools/controller.h"
#include "tools/ink.h"
#include "tools/intertwine.h"
#include "tools/point_shape.h"
#include "tools/tool_loop.h"
#include "util/render.h"
using namespace gfx; using namespace gfx;
using namespace tools;
////////////////////////////////////////////////////////////////////// ToolLoopManager::ToolLoopManager(ToolLoop* toolLoop)
// ToolPointShape class
void ToolPointShape::doInkHline(int x1, int y, int x2, IToolLoop* loop)
{
register int w, size; // width or height
register int x;
// Tiled in Y axis
if (loop->getTiledMode() & TILED_Y_AXIS) {
size = loop->getDstImage()->h; // size = image height
if (y < 0)
y = size - (-(y+1) % size) - 1;
else
y = y % size;
}
else if (y < 0 || y >= loop->getDstImage()->h)
return;
// Tiled in X axis
if (loop->getTiledMode() & TILED_X_AXIS) {
if (x1 > x2)
return;
size = loop->getDstImage()->w; // size = image width
w = x2-x1+1;
if (w >= size)
loop->getInk()->inkHline(0, y, size-1, loop);
else {
x = x1;
if (x < 0)
x = size - (-(x+1) % size) - 1;
else
x = x % size;
if (x+w-1 <= size-1)
loop->getInk()->inkHline(x, y, x+w-1, loop);
else {
loop->getInk()->inkHline(x, y, size-1, loop);
loop->getInk()->inkHline(0, y, w-(size-x)-1, loop);
}
}
}
// Clipped in X axis
else {
if (x1 < 0)
x1 = 0;
if (x2 >= loop->getDstImage()->w)
x2 = loop->getDstImage()->w-1;
if (x2-x1+1 < 1)
return;
loop->getInk()->inkHline(x1, y, x2, loop);
}
}
//////////////////////////////////////////////////////////////////////
// ToolIntertwine class
void ToolIntertwine::doPointshapePoint(int x, int y, IToolLoop* loop)
{
loop->getPointShape()->transformPoint(loop, x, y);
}
void ToolIntertwine::doPointshapeHline(int x1, int y, int x2, IToolLoop* loop)
{
algo_line(x1, y, x2, y, loop, (AlgoPixel)doPointshapePoint);
}
void ToolIntertwine::doPointshapeLine(int x1, int y1, int x2, int y2, IToolLoop* loop)
{
algo_line(x1, y1, x2, y2, loop, (AlgoPixel)doPointshapePoint);
}
//////////////////////////////////////////////////////////////////////
// ToolLoopManager class
ToolLoopManager::ToolLoopManager(IToolLoop* toolLoop)
: m_toolLoop(toolLoop) : m_toolLoop(toolLoop)
{ {
} }
@ -115,6 +42,11 @@ ToolLoopManager::~ToolLoopManager()
delete m_toolLoop; delete m_toolLoop;
} }
bool ToolLoopManager::isCanceled() const
{
return m_toolLoop->isCanceled();
}
void ToolLoopManager::prepareLoop(const Pointer& pointer) void ToolLoopManager::prepareLoop(const Pointer& pointer)
{ {
// Start with no points at all // Start with no points at all
@ -202,7 +134,7 @@ void ToolLoopManager::doLoopStep(bool last_step)
{ {
static Rect old_dirty_area; // TODO Not thread safe static Rect old_dirty_area; // TODO Not thread safe
std::vector<Point> points_to_interwine; Points points_to_interwine;
if (!last_step) if (!last_step)
m_toolLoop->getController()->getPointsToInterwine(m_points, points_to_interwine); m_toolLoop->getController()->getPointsToInterwine(m_points, points_to_interwine);
else else
@ -214,18 +146,18 @@ void ToolLoopManager::doLoopStep(bool last_step)
switch (m_toolLoop->getTracePolicy()) { switch (m_toolLoop->getTracePolicy()) {
case TOOL_TRACE_POLICY_ACCUMULATE: case TracePolicyAccumulate:
// Do nothing. We accumulate traces in the destination image. // Do nothing. We accumulate traces in the destination image.
break; break;
case TOOL_TRACE_POLICY_LAST: case TracePolicyLast:
// Copy source to destination (reset the previous trace). Useful // Copy source to destination (reset the previous trace). Useful
// for tools like Line and Ellipse tools (we kept the last trace only). // for tools like Line and Ellipse tools (we kept the last trace only).
image_clear(m_toolLoop->getDstImage(), 0); image_clear(m_toolLoop->getDstImage(), 0);
image_copy(m_toolLoop->getDstImage(), m_toolLoop->getSrcImage(), 0, 0); image_copy(m_toolLoop->getDstImage(), m_toolLoop->getSrcImage(), 0, 0);
break; break;
case TOOL_TRACE_POLICY_OVERLAP: case TracePolicyOverlap:
// Copy destination to source (yes, destination to source). In // Copy destination to source (yes, destination to source). In
// this way each new trace overlaps the previous one. // this way each new trace overlaps the previous one.
image_copy(m_toolLoop->getSrcImage(), m_toolLoop->getDstImage(), 0, 0); image_copy(m_toolLoop->getSrcImage(), m_toolLoop->getDstImage(), 0, 0);
@ -243,7 +175,7 @@ void ToolLoopManager::doLoopStep(bool last_step)
calculateDirtyArea(m_toolLoop, points_to_interwine, dirty_area); calculateDirtyArea(m_toolLoop, points_to_interwine, dirty_area);
Rect new_dirty_area; Rect new_dirty_area;
if (m_toolLoop->getTracePolicy() == TOOL_TRACE_POLICY_LAST) { if (m_toolLoop->getTracePolicy() == TracePolicyLast) {
new_dirty_area = old_dirty_area.createUnion(dirty_area); new_dirty_area = old_dirty_area.createUnion(dirty_area);
old_dirty_area = dirty_area; old_dirty_area = dirty_area;
} }
@ -283,7 +215,7 @@ void ToolLoopManager::snapToGrid(bool flexible, Point& point)
point.y = dy.rem + d.quot*h + ((d.rem > h/2)? h-flexible: 0); point.y = dy.rem + d.quot*h + ((d.rem > h/2)? h-flexible: 0);
} }
void ToolLoopManager::calculateDirtyArea(IToolLoop* loop, const std::vector<Point>& points, Rect& dirty_area) void ToolLoopManager::calculateDirtyArea(ToolLoop* loop, const Points& points, Rect& dirty_area)
{ {
Point minpt, maxpt; Point minpt, maxpt;
calculateMinMax(points, minpt, maxpt); calculateMinMax(points, minpt, maxpt);
@ -295,7 +227,7 @@ void ToolLoopManager::calculateDirtyArea(IToolLoop* loop, const std::vector<Poin
dirty_area = r1.createUnion(r2); dirty_area = r1.createUnion(r2);
} }
void ToolLoopManager::calculateMinMax(const std::vector<Point>& points, Point& minpt, Point& maxpt) void ToolLoopManager::calculateMinMax(const Points& points, Point& minpt, Point& maxpt)
{ {
ASSERT(points.size() > 0); ASSERT(points.size() > 0);

View File

@ -0,0 +1,116 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2011 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TOOLS_TOOL_LOOP_MANAGER_H_INCLUDED
#define TOOLS_TOOL_LOOP_MANAGER_H_INCLUDED
#include <vector>
#include "gfx/point.h"
#include "gfx/rect.h"
namespace tools {
class ToolLoop;
// Class to manage the drawing tool (editor <-> tool interface).
//
// The flow is this:
// 1. The user press a mouse button in a Editor widget
// 2. The Editor creates an implementation of ToolLoop and use it
// with the ToolLoopManager constructor
// 3. The ToolLoopManager is used to call
// the following methods:
// - ToolLoopManager::prepareLoop
// - ToolLoopManager::pressButton
// 4. If the user moves the mouse, the method
// - ToolLoopManager::movement
// is called.
// 5. When the user release the mouse:
// - ToolLoopManager::releaseButton
// - ToolLoopManager::releaseLoop
class ToolLoopManager
{
public:
// Simple container of mouse events information.
class Pointer
{
public:
enum Button { Left, Middle, Right };
Pointer(int x, int y, Button button)
: m_x(x), m_y(y), m_button(button) { }
int getX() const { return m_x; }
int getY() const { return m_y; }
Button getButton() const { return m_button; }
private:
int m_x, m_y;
Button m_button;
};
// Contructs a manager for the ToolLoop delegate.
ToolLoopManager(ToolLoop* toolLoop);
virtual ~ToolLoopManager();
bool isCanceled() const;
// Should be called when the user start a tool-trace (pressing the
// left or right button for first time in the editor).
void prepareLoop(const Pointer& pointer);
// Called when the loop is over.
void releaseLoop(const Pointer& pointer);
// Should be called each time the user presses a mouse button.
void pressButton(const Pointer& pointer);
// Should be called each time the user releases a mouse button.
//
// Returns true if the tool-loop should continue, or false
// if the editor should release the mouse capture.
bool releaseButton(const Pointer& pointer);
// Should be called each time the user moves the mouse inside the editor.
void movement(const Pointer& pointer);
private:
typedef std::vector<gfx::Point> Points;
void doLoopStep(bool last_step);
void snapToGrid(bool flexible, gfx::Point& point);
static void calculateDirtyArea(ToolLoop* loop,
const Points& points,
gfx::Rect& dirty_area);
static void calculateMinMax(const Points& points,
gfx::Point& minpt,
gfx::Point& maxpt);
ToolLoop* m_toolLoop;
Points m_points;
gfx::Point m_oldPoint;
};
} // namespace tools
#endif // TOOLS_TOOL_H_INCLUDED

33
src/tools/trace_policy.h Normal file
View File

@ -0,0 +1,33 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2011 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TOOLS_TRACE_POLICY_H_INCLUDED
#define TOOLS_TRACE_POLICY_H_INCLUDED
namespace tools {
enum TracePolicy
{
TracePolicyAccumulate,
TracePolicyLast,
TracePolicyOverlap,
};
} // namespace tools
#endif // TOOLS_TRACE_POLICY_H_INCLUDED

View File

@ -18,9 +18,6 @@
#include "config.h" #include "config.h"
#include <allegro.h>
#include <algorithm>
#include "app.h" #include "app.h"
#include "app/color.h" #include "app/color.h"
#include "app/color_utils.h" #include "app/color_utils.h"
@ -37,11 +34,15 @@
#include "raster/layer.h" #include "raster/layer.h"
#include "raster/pen.h" #include "raster/pen.h"
#include "raster/sprite.h" #include "raster/sprite.h"
#include "tools/ink.h"
#include "tools/tool.h" #include "tools/tool.h"
#include "ui_context.h" #include "ui_context.h"
#include "util/boundary.h" #include "util/boundary.h"
#include "widgets/editor/editor.h" #include "widgets/editor/editor.h"
#include <algorithm>
#include <allegro.h>
#ifdef WIN32 #ifdef WIN32
#undef max #undef max
#undef min #undef min
@ -172,7 +173,7 @@ static void on_pen_size_after_change()
static Pen* editor_get_current_pen() static Pen* editor_get_current_pen()
{ {
// Create the current pen from settings // Create the current pen from settings
Tool* current_tool = UIContext::instance() tools::Tool* current_tool = UIContext::instance()
->getSettings() ->getSettings()
->getCurrentTool(); ->getCurrentTool();
@ -253,7 +254,7 @@ void Editor::editor_draw_cursor(int x, int y, bool refresh)
screenToEditor(x, y, &x, &y); screenToEditor(x, y, &x, &y);
// Get the current tool // Get the current tool
Tool* current_tool = UIContext::instance() tools::Tool* current_tool = UIContext::instance()
->getSettings() ->getSettings()
->getCurrentTool(); ->getCurrentTool();
@ -461,14 +462,16 @@ bool Editor::editor_cursor_is_subpixel()
static void generate_cursor_boundaries() static void generate_cursor_boundaries()
{ {
Tool* current_tool = UIContext::instance() tools::Tool* current_tool = UIContext::instance()
->getSettings() ->getSettings()
->getCurrentTool(); ->getCurrentTool();
IPenSettings* pen_settings = UIContext::instance() IPenSettings* pen_settings = NULL;
->getSettings() if (current_tool)
->getToolSettings(current_tool) pen_settings = UIContext::instance()
->getPen(); ->getSettings()
->getToolSettings(current_tool)
->getPen();
if (cursor_bound.seg == NULL || if (cursor_bound.seg == NULL ||
cursor_bound.pen_type != pen_settings->getType() || cursor_bound.pen_type != pen_settings->getType() ||
@ -483,12 +486,7 @@ static void generate_cursor_boundaries()
Pen* pen; Pen* pen;
UIContext* context = UIContext::instance(); if (pen_settings) {
Tool* current_tool = context->getSettings()->getCurrentTool();
if (current_tool) {
IPenSettings* pen_settings = context->getSettings()
->getToolSettings(current_tool)->getPen();
ASSERT(pen_settings != NULL);
pen = new Pen(pen_settings->getType(), pen = new Pen(pen_settings->getType(),
pen_settings->getSize(), pen_settings->getSize(),
pen_settings->getAngle()); pen_settings->getAngle());

View File

@ -37,7 +37,10 @@
#include "raster/raster.h" #include "raster/raster.h"
#include "settings/settings.h" #include "settings/settings.h"
#include "skin/skin_theme.h" #include "skin/skin_theme.h"
#include "tools/ink.h"
#include "tools/tool.h" #include "tools/tool.h"
#include "tools/tool_loop.h"
#include "tools/tool_loop_manager.h"
#include "ui_context.h" #include "ui_context.h"
#include "undo/undo_history.h" #include "undo/undo_history.h"
#include "undoers/add_cel.h" #include "undoers/add_cel.h"
@ -66,6 +69,7 @@
KB_CTRL_FLAG)) == (shift)) KB_CTRL_FLAG)) == (shift))
using namespace gfx; using namespace gfx;
using namespace tools;
static bool editor_view_msg_proc(JWidget widget, JMessage msg); static bool editor_view_msg_proc(JWidget widget, JMessage msg);
@ -1066,7 +1070,7 @@ bool Editor::onProcessMessage(JMessage msg)
else if (m_sprite->getCurrentLayer()) { else if (m_sprite->getCurrentLayer()) {
ASSERT(m_toolLoopManager == NULL); ASSERT(m_toolLoopManager == NULL);
IToolLoop* toolLoop = createToolLoopImpl(UIContext::instance(), msg); ToolLoop* toolLoop = createToolLoopImpl(UIContext::instance(), msg);
if (!toolLoop) if (!toolLoop)
return true; // Return without capturing mouse return true; // Return without capturing mouse
@ -1631,9 +1635,9 @@ void Editor::setZoomAndCenterInMouse(int zoom, int mouse_x, int mouse_y)
} }
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// IToolLoop implementation // ToolLoop implementation
class ToolLoopImpl : public IToolLoop class ToolLoopImpl : public ToolLoop
{ {
Editor* m_editor; Editor* m_editor;
Context* m_context; Context* m_context;
@ -1694,13 +1698,13 @@ public:
m_tiled_mode = settings->getTiledMode(); m_tiled_mode = settings->getTiledMode();
switch (tool->getFill(m_button)) { switch (tool->getFill(m_button)) {
case TOOL_FILL_NONE: case FillNone:
m_filled = false; m_filled = false;
break; break;
case TOOL_FILL_ALWAYS: case FillAlways:
m_filled = true; m_filled = true;
break; break;
case TOOL_FILL_OPTIONAL: case FillOptional:
m_filled = settings->getToolSettings(m_tool)->getFilled(); m_filled = settings->getToolSettings(m_tool)->getFilled();
break; break;
} }
@ -1944,11 +1948,11 @@ public:
Point getOffset() { return m_offset; } Point getOffset() { return m_offset; }
void setSpeed(const Point& speed) { m_speed = speed; } void setSpeed(const Point& speed) { m_speed = speed; }
Point getSpeed() { return m_speed; } Point getSpeed() { return m_speed; }
ToolInk* getInk() { return m_tool->getInk(m_button); } Ink* getInk() { return m_tool->getInk(m_button); }
ToolController* getController() { return m_tool->getController(m_button); } Controller* getController() { return m_tool->getController(m_button); }
ToolPointShape* getPointShape() { return m_tool->getPointShape(m_button); } PointShape* getPointShape() { return m_tool->getPointShape(m_button); }
ToolIntertwine* getIntertwine() { return m_tool->getIntertwine(m_button); } Intertwine* getIntertwine() { return m_tool->getIntertwine(m_button); }
ToolTracePolicy getTracePolicy() { return m_tool->getTracePolicy(m_button); } TracePolicy getTracePolicy() { return m_tool->getTracePolicy(m_button); }
void cancel() { m_canceled = true; } void cancel() { m_canceled = true; }
bool isCanceled() { return m_canceled; } bool isCanceled() { return m_canceled; }
@ -1977,10 +1981,9 @@ public:
{ {
app_get_statusbar()->setStatusText(0, text); app_get_statusbar()->setStatusText(0, text);
} }
}; };
IToolLoop* Editor::createToolLoopImpl(Context* context, JMessage msg) ToolLoop* Editor::createToolLoopImpl(Context* context, JMessage msg)
{ {
Tool* current_tool = context->getSettings()->getCurrentTool(); Tool* current_tool = context->getSettings()->getCurrentTool();
if (!current_tool) if (!current_tool)

View File

@ -30,13 +30,16 @@
#define MAX_ZOOM 5 #define MAX_ZOOM 5
class Context; class Context;
class IToolLoop;
class PixelsMovement; class PixelsMovement;
class Sprite; class Sprite;
class Tool;
class ToolLoopManager;
class View; class View;
namespace tools {
class Tool;
class ToolLoop;
class ToolLoopManager;
}
class Editor : public Widget class Editor : public Widget
{ {
@ -66,7 +69,7 @@ class Editor : public Widget
// Current selected quicktool (this genererally should be NULL if // Current selected quicktool (this genererally should be NULL if
// the user is not pressing any keyboard key). // the user is not pressing any keyboard key).
Tool* m_quicktool; tools::Tool* m_quicktool;
/* offset for the sprite */ /* offset for the sprite */
int m_offset_x; int m_offset_x;
@ -80,7 +83,7 @@ class Editor : public Widget
JRegion m_refresh_region; JRegion m_refresh_region;
// Tool-loop manager // Tool-loop manager
ToolLoopManager* m_toolLoopManager; tools::ToolLoopManager* m_toolLoopManager;
// Helper member to move selection. If this member is NULL it means the // Helper member to move selection. If this member is NULL it means the
// user is not moving pixels. // user is not moving pixels.
@ -190,14 +193,14 @@ private:
void controlInfiniteScroll(JMessage msg); void controlInfiniteScroll(JMessage msg);
void dropPixels(); void dropPixels();
Tool* getCurrentEditorTool(); tools::Tool* getCurrentEditorTool();
void editor_request_size(int *w, int *h); void editor_request_size(int *w, int *h);
void editor_setcursor(int x, int y); void editor_setcursor(int x, int y);
void editor_update_candraw(); void editor_update_candraw();
void setZoomAndCenterInMouse(int zoom, int mouse_x, int mouse_y); void setZoomAndCenterInMouse(int zoom, int mouse_x, int mouse_y);
IToolLoop* createToolLoopImpl(Context* context, JMessage msg); tools::ToolLoop* createToolLoopImpl(Context* context, JMessage msg);
void for_each_pixel_of_pen(int screen_x, int screen_y, void for_each_pixel_of_pen(int screen_x, int screen_y,
int sprite_x, int sprite_y, int color, int sprite_x, int sprite_y, int color,

View File

@ -167,10 +167,10 @@ StatusBar::~StatusBar()
void StatusBar::onCurrentToolChange() void StatusBar::onCurrentToolChange()
{ {
if (isVisible()) { if (isVisible()) {
Tool* currentTool = UIContext::instance()->getSettings()->getCurrentTool(); tools::Tool* currentTool = UIContext::instance()->getSettings()->getCurrentTool();
if (currentTool) { if (currentTool) {
this->showTool(500, currentTool); showTool(500, currentTool);
this->setTextf("%s Selected", currentTool->getText().c_str()); setTextf("%s Selected", currentTool->getText().c_str());
} }
} }
} }
@ -257,7 +257,7 @@ void StatusBar::showColor(int msecs, const char* text, const Color& color, int a
} }
} }
void StatusBar::showTool(int msecs, Tool* tool) void StatusBar::showTool(int msecs, tools::Tool* tool)
{ {
ASSERT(tool != NULL); ASSERT(tool != NULL);

View File

@ -32,7 +32,8 @@ class ColorButton;
class Frame; class Frame;
class Slider; class Slider;
class StatusBar; class StatusBar;
class Tool;
namespace tools { class Tool; }
class Progress class Progress
{ {
@ -61,7 +62,7 @@ public:
bool setStatusText(int msecs, const char *format, ...); bool setStatusText(int msecs, const char *format, ...);
void showTip(int msecs, const char *format, ...); void showTip(int msecs, const char *format, ...);
void showColor(int msecs, const char* text, const Color& color, int alpha); void showColor(int msecs, const char* text, const Color& color, int alpha);
void showTool(int msecs, Tool* tool); void showTool(int msecs, tools::Tool* tool);
void showMovePixelsOptions(); void showMovePixelsOptions();
void hideMovePixelsOptions(); void hideMovePixelsOptions();
@ -88,7 +89,7 @@ private:
State m_state; State m_state;
// Showing a tool // Showing a tool
Tool* m_tool; tools::Tool* m_tool;
// Showing a color // Showing a color
Color m_color; Color m_color;

View File

@ -31,7 +31,7 @@
#include "modules/gfx.h" #include "modules/gfx.h"
#include "modules/gui.h" #include "modules/gui.h"
#include "skin/skin_theme.h" #include "skin/skin_theme.h"
#include "tools/toolbox.h" #include "tools/tool_box.h"
#include "ui_context.h" #include "ui_context.h"
#include "widgets/groupbut.h" #include "widgets/groupbut.h"
#include "widgets/statebar.h" #include "widgets/statebar.h"
@ -41,6 +41,7 @@
#include <string> #include <string>
using namespace gfx; using namespace gfx;
using namespace tools;
// Class to show selected tools for each tool (vertically) // Class to show selected tools for each tool (vertically)
class ToolBar : public Widget class ToolBar : public Widget

View File

@ -21,11 +21,11 @@
#include "gui/base.h" #include "gui/base.h"
class Tool; namespace tools { class Tool; }
JWidget toolbar_new(); JWidget toolbar_new();
bool toolbar_is_tool_visible(JWidget toolbar, Tool* tool); bool toolbar_is_tool_visible(JWidget toolbar, tools::Tool* tool);
void toolbar_select_tool(JWidget toolbar, Tool* tool); void toolbar_select_tool(JWidget toolbar, tools::Tool* tool);
#endif #endif