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_property.cpp
skin/skin_slider_property.cpp
tools/tool.cpp
tools/toolbox.cpp
tools/intertwine.cpp
tools/point_shape.cpp
tools/tool_box.cpp
tools/tool_loop_manager.cpp
undoers/add_cel.cpp
undoers/add_image.cpp
undoers/add_layer.cpp

View File

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

View File

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

View File

@ -62,7 +62,7 @@ void ChangePenCommand::onLoadParams(Params* params)
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);
IPenSettings* pen = tool_settings->getPen();

View File

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

View File

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

View File

@ -33,9 +33,10 @@ class Document;
class Frame;
class Params;
class RadioButton;
class Tool;
class Widget;
namespace tools { class Tool; }
//////////////////////////////////////////////////////////////////////
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
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_quicktool(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, tools::Tool* tool);
Command* get_command_from_key_message(JMessage msg);
JAccel get_accel_to_execute_command(const char* command, Params* params = NULL);
JAccel get_accel_to_change_tool(Tool* tool);
Tool* get_selected_quicktool();
JAccel get_accel_to_change_tool(tools::Tool* tool);
tools::Tool* get_selected_quicktool();
//////////////////////////////////////////////////////////////////////
// Monitors

View File

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

View File

@ -26,7 +26,8 @@
class IToolSettings;
class IPenSettings;
class Tool;
namespace tools { class Tool; }
// Settings used in tool <-> drawing <-> editor stuff
class ISettings
@ -38,12 +39,12 @@ public:
virtual Color getFgColor() = 0;
virtual Color getBgColor() = 0;
virtual Tool* getCurrentTool() = 0;
virtual tools::Tool* getCurrentTool() = 0;
virtual TiledMode getTiledMode() = 0;
virtual void setFgColor(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;
// Grid settings
@ -82,7 +83,7 @@ public:
// 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 <allegro/color.h>
#include <string>
#include "settings/ui_settings_impl.h"
#include "app.h"
#include "core/cfg.h"
#include "settings/ui_settings_impl.h"
#include "ui_context.h"
#include "tools/point_shape.h"
#include "tools/tool.h"
#include "tools/toolbox.h"
#include "tools/tool_box.h"
#include "ui_context.h"
#include "widgets/color_bar.h"
#include <allegro/color.h>
#include <string>
using namespace gfx;
//////////////////////////////////////////////////////////////////////
@ -87,7 +89,7 @@ Color UISettingsImpl::getBgColor()
return app_get_colorbar()->getBgColor();
}
Tool* UISettingsImpl::getCurrentTool()
tools::Tool* UISettingsImpl::getCurrentTool()
{
if (!m_currentTool)
m_currentTool = App::instance()->getToolBox()->getToolById("pencil");
@ -110,7 +112,7 @@ void UISettingsImpl::setBgColor(const Color& color)
app_get_colorbar()->setFgColor(color);
}
void UISettingsImpl::setCurrentTool(Tool* tool)
void UISettingsImpl::setCurrentTool(tools::Tool* tool)
{
if (m_currentTool != tool) {
// Fire PenSizeBeforeChange signal (maybe the new selected tool has a different pen size)
@ -308,7 +310,7 @@ public:
class UIToolSettingsImpl : public IToolSettings
{
Tool* m_tool;
tools::Tool* m_tool;
UIPenSettingsImpl m_pen;
int m_opacity;
int m_tolerance;
@ -319,7 +321,7 @@ class UIToolSettingsImpl : public IToolSettings
public:
UIToolSettingsImpl(Tool* tool)
UIToolSettingsImpl(tools::Tool* tool)
: m_tool(tool)
{
std::string cfg_section(getCfgSection());
@ -387,7 +389,7 @@ private:
}
};
IToolSettings* UISettingsImpl::getToolSettings(Tool* tool)
IToolSettings* UISettingsImpl::getToolSettings(tools::Tool* tool)
{
ASSERT(tool != NULL);

View File

@ -33,12 +33,12 @@ public:
Color getFgColor();
Color getBgColor();
Tool* getCurrentTool();
tools::Tool* getCurrentTool();
TiledMode getTiledMode();
void setFgColor(const Color& color);
void setBgColor(const Color& color);
void setCurrentTool(Tool* tool);
void setCurrentTool(tools::Tool* tool);
void setTiledMode(TiledMode mode);
// Grid settings
@ -77,10 +77,10 @@ public:
// Tools settings
IToolSettings* getToolSettings(Tool* tool);
IToolSettings* getToolSettings(tools::Tool* tool);
private:
Tool* m_currentTool;
tools::Tool* m_currentTool;
TiledMode m_tiledMode;
bool m_use_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
// Controls clicks for tools like pencil
class FreehandController : public ToolController
class FreehandController : public Controller
{
public:
void pressButton(std::vector<Point>& points, const Point& point)
void pressButton(Points& points, const Point& point)
{
points.push_back(point);
}
bool releaseButton(std::vector<Point>& points, const Point& point)
bool releaseButton(Points& points, const Point& point)
{
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);
}
void getPointsToInterwine(const std::vector<Point>& input, std::vector<Point>& output)
void getPointsToInterwine(const Points& input, Points& output)
{
if (input.size() == 1) {
output.push_back(input[0]);
@ -49,7 +49,7 @@ public:
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];
sprintf(buf, "Start %3d %3d End %3d %3d",
@ -61,22 +61,22 @@ public:
};
// Controls clicks for tools like line
class TwoPointsController : public ToolController
class TwoPointsController : public Controller
{
Point m_center;
public:
void pressButton(std::vector<Point>& points, const Point& point)
void pressButton(Points& points, const Point& point)
{
m_center = 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;
}
void movement(IToolLoop* loop, std::vector<Point>& points, const Point& point)
void movement(ToolLoop* loop, Points& points, const Point& point)
{
points[1] = point;
@ -136,12 +136,12 @@ public:
else
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[1]);
}
void getStatusBarText(const std::vector<Point>& points, std::string& text)
void getStatusBarText(const Points& points, std::string& text)
{
char buf[1024];
sprintf(buf, "Start %3d %3d End %3d %3d (Size %3d %3d) Angle %.1f",
@ -156,15 +156,15 @@ public:
};
// Controls clicks for tools like polygon
class PointByPointController : public ToolController
class PointByPointController : public Controller
{
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)
{
if (points[points.size()-2] == point &&
points[points.size()-1] == point)
@ -172,15 +172,15 @@ public:
else
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;
}
void getPointsToInterwine(const std::vector<Point>& input, std::vector<Point>& output)
void getPointsToInterwine(const Points& input, Points& output)
{
output = input;
}
void getStatusBarText(const std::vector<Point>& points, std::string& text)
void getStatusBarText(const Points& points, std::string& text)
{
char buf[1024];
sprintf(buf, "Start %3d %3d End %3d %3d",
@ -191,30 +191,30 @@ public:
}
};
class OnePointController : public ToolController
class OnePointController : public Controller
{
public:
// Do not apply grid to "one point tools" (e.g. magic wand, flood fill, etc.)
bool canSnapToGrid() { return false; }
void pressButton(std::vector<Point>& points, const Point& point)
void pressButton(Points& points, const Point& point)
{
if (points.size() == 0)
points.push_back(point);
}
bool releaseButton(std::vector<Point>& points, const Point& point)
bool releaseButton(Points& points, const Point& point)
{
return false;
}
void movement(IToolLoop* loop, std::vector<Point>& points, const Point& point)
void movement(ToolLoop* loop, Points& points, const Point& point)
{
// Do nothing
}
void getPointsToInterwine(const std::vector<Point>& input, std::vector<Point>& output)
void getPointsToInterwine(const Points& input, Points& output)
{
output = input;
}
void getStatusBarText(const std::vector<Point>& points, std::string& text)
void getStatusBarText(const Points& points, std::string& text)
{
char buf[1024];
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;
public:
void pressButton(std::vector<Point>& points, const Point& point)
void pressButton(Points& points, const Point& point)
{
if (points.size() == 0) {
points.resize(4, point);
@ -235,12 +235,12 @@ public:
else
m_clickCounter++;
}
bool releaseButton(std::vector<Point>& points, const Point& point)
bool releaseButton(Points& points, const Point& point)
{
m_clickCounter++;
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) {
case 0:
@ -257,11 +257,11 @@ public:
break;
}
}
void getPointsToInterwine(const std::vector<Point>& input, std::vector<Point>& output)
void getPointsToInterwine(const Points& input, Points& output)
{
output = input;
}
void getStatusBarText(const std::vector<Point>& points, std::string& text)
void getStatusBarText(const Points& points, std::string& text)
{
char buf[1024];
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
//////////////////////////////////////////////////////////////////////
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();
@ -92,7 +92,7 @@ static void ink_hline32_opaque(int x1, int y, int x2, IToolLoop* loop)
*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();
@ -101,7 +101,7 @@ static void ink_hline16_opaque(int x1, int y, int x2, IToolLoop* loop)
*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();
@ -116,7 +116,7 @@ static void ink_hline8_opaque(int x1, int y, int x2, IToolLoop* loop)
// 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 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));
}
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 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));
}
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();
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();
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();
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();
RgbMap* rgbmap = loop->getSprite()->getRgbMap();
@ -314,7 +314,7 @@ static void ink_hline8_blur(int x1, int y, int x2, IToolLoop* loop)
// 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 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 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();
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);
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();
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();
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 RgbMap* rgbmap = loop->getSprite()->getRgbMap();

View File

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

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
*/
class IntertwineNone : public ToolIntertwine
class IntertwineNone : public Intertwine
{
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)
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);
}
};
class IntertwineAsLines : public ToolIntertwine
class IntertwineAsLines : public Intertwine
{
public:
bool snapByAngle() { return true; }
void joinPoints(IToolLoop* loop, const std::vector<Point>& points)
void joinPoints(ToolLoop* loop, const Points& points)
{
if (points.size() == 0)
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) {
joinPoints(loop, points);
@ -79,11 +79,11 @@ public:
}
};
class IntertwineAsRectangles : public ToolIntertwine
class IntertwineAsRectangles : public Intertwine
{
public:
void joinPoints(IToolLoop* loop, const std::vector<Point>& points)
void joinPoints(ToolLoop* loop, const Points& points)
{
if (points.size() == 0)
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) {
joinPoints(loop, points);
@ -136,11 +136,11 @@ public:
}
};
class IntertwineAsEllipses : public ToolIntertwine
class IntertwineAsEllipses : public Intertwine
{
public:
void joinPoints(IToolLoop* loop, const std::vector<Point>& points)
void joinPoints(ToolLoop* loop, const Points& points)
{
if (points.size() == 0)
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) {
joinPoints(loop, points);
@ -184,11 +184,11 @@ public:
}
};
class IntertwineAsBezier : public ToolIntertwine
class IntertwineAsBezier : public Intertwine
{
public:
void joinPoints(IToolLoop* loop, const std::vector<Point>& points)
void joinPoints(ToolLoop* loop, const Points& points)
{
if (points.size() == 0)
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);
}

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
*/
class NonePointShape : public ToolPointShape
class NonePointShape : public PointShape
{
public:
void transformPoint(IToolLoop* loop, int x, int y)
void transformPoint(ToolLoop* loop, int x, int y)
{
// Do nothing
}
void getModifiedArea(IToolLoop* loop, int x, int y, Rect& area)
void getModifiedArea(ToolLoop* loop, int x, int y, Rect& area)
{
// Do nothing
}
};
class PixelPointShape : public ToolPointShape
class PixelPointShape : public PointShape
{
public:
void transformPoint(IToolLoop* loop, int x, int y)
void transformPoint(ToolLoop* loop, int x, int y)
{
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);
}
};
class PenPointShape : public ToolPointShape
class PenPointShape : public PointShape
{
public:
void transformPoint(IToolLoop* loop, int x, int y)
void transformPoint(ToolLoop* loop, int x, int y)
{
Pen* pen = loop->getPen();
std::vector<PenScanline>::const_iterator scanline = pen->get_scanline().begin();
@ -61,7 +61,7 @@ public:
++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();
int size = pen->get_size();
@ -69,22 +69,22 @@ public:
}
};
class FloodFillPointShape : public ToolPointShape
class FloodFillPointShape : public PointShape
{
public:
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);
}
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);
}
};
class SprayPointShape : public ToolPointShape
class SprayPointShape : public PointShape
{
PenPointShape m_subPointShape;
@ -92,7 +92,7 @@ public:
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_speed = loop->getSpraySpeed();
@ -123,7 +123,7 @@ public:
#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();
Point p1(x-spray_width, y-spray_width);

View File

@ -19,163 +19,22 @@
#ifndef TOOLS_TOOL_H_INCLUDED
#define TOOLS_TOOL_H_INCLUDED
#include <list>
#include <string>
#include <vector>
#include "filters/tiled_mode.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "tools/fill.h"
#include "tools/trace_policy.h"
class Context;
class Document;
class Image;
class Layer;
class Mask;
class Pen;
class Sprite;
class Tool;
namespace tools {
class IToolLoop;
enum ToolFill
{
TOOL_FILL_NONE,
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; }
};
class Controller;
class Ink;
class Intertwine;
class PointShape;
class ToolGroup;
// A drawing 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:
Tool(ToolGroup* group,
@ -199,223 +58,39 @@ public:
const std::string& getTips() const { return m_tips; }
int getDefaultPenSize() const { return m_default_pen_size; }
ToolFill getFill(int button) { return m_button[button].m_fill; }
ToolInk* getInk(int button) { return m_button[button].m_ink; }
ToolController* getController(int button) { return m_button[button].m_controller; }
ToolPointShape* getPointShape(int button) { return m_button[button].m_point_shape; }
ToolIntertwine* getIntertwine(int button) { return m_button[button].m_intertwine; }
ToolTracePolicy getTracePolicy(int button) { return m_button[button].m_trace_policy; }
Fill getFill(int button) { return m_button[button].m_fill; }
Ink* getInk(int button) { return m_button[button].m_ink; }
Controller* getController(int button) { return m_button[button].m_controller; }
PointShape* getPointShape(int button) { return m_button[button].m_point_shape; }
Intertwine* getIntertwine(int button) { return m_button[button].m_intertwine; }
TracePolicy getTracePolicy(int button) { return m_button[button].m_trace_policy; }
void setFill(int button, ToolFill fill) { m_button[button].m_fill = fill; }
void setInk(int button, ToolInk* ink) { m_button[button].m_ink = ink; }
void setController(int button, ToolController* controller) { m_button[button].m_controller = controller; }
void setPointShape(int button, ToolPointShape* point_shape) { m_button[button].m_point_shape = point_shape; }
void setIntertwine(int button, ToolIntertwine* intertwine) { m_button[button].m_intertwine = intertwine; }
void setTracePolicy(int button, ToolTracePolicy 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);
void setFill(int button, Fill fill) { m_button[button].m_fill = fill; }
void setInk(int button, Ink* ink) { m_button[button].m_ink = ink; }
void setController(int button, Controller* controller) { m_button[button].m_controller = controller; }
void setPointShape(int button, PointShape* point_shape) { m_button[button].m_point_shape = point_shape; }
void setIntertwine(int button, Intertwine* intertwine) { m_button[button].m_intertwine = intertwine; }
void setTracePolicy(int button, TracePolicy trace_policy) { m_button[button].m_trace_policy = trace_policy; }
private:
void doLoopStep(bool last_step);
void snapToGrid(bool flexible, gfx::Point& point);
ToolGroup* m_group;
std::string m_id;
std::string m_text;
std::string m_tips;
int m_default_pen_size;
static void calculateDirtyArea(IToolLoop* loop,
const std::vector<gfx::Point>& points,
gfx::Rect& dirty_area);
struct {
Fill m_fill;
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 <algorithm>
#include <allegro/file.h>
#include <allegro/fixed.h>
#include <allegro/fmaths.h>
#include "base/exception.h"
#include "gui_xml.h"
#include "raster/algo.h"
#include "raster/image.h"
#include "raster/mask.h"
#include "raster/pen.h"
#include "raster/sprite.h"
#include "tools/toolbox.h"
#include "tools/controller.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 tools;
#include "tools/controllers.h"
#include "tools/inks.h"
@ -181,51 +187,51 @@ void ToolBox::loadToolProperties(TiXmlElement* xmlTool, Tool* tool, int button,
if (!tracepolicy) tracepolicy = xmlTool->Attribute("tracepolicy");
// Fill
ToolFill fill_value = TOOL_FILL_NONE;
Fill fill_value = FillNone;
if (fill) {
if (strcmp(fill, "none") == 0)
fill_value = TOOL_FILL_NONE;
fill_value = FillNone;
else if (strcmp(fill, "always") == 0)
fill_value = TOOL_FILL_ALWAYS;
fill_value = FillAlways;
else if (strcmp(fill, "optional") == 0)
fill_value = TOOL_FILL_OPTIONAL;
fill_value = FillOptional;
else
throw base::Exception("Invalid fill '%s' specified in '%s' tool.\n", fill, tool_id);
}
// Find the ink
std::map<std::string, ToolInk*>::iterator it_ink
std::map<std::string, Ink*>::iterator it_ink
= m_inks.find(ink ? ink: "");
if (it_ink == m_inks.end())
throw base::Exception("Invalid ink '%s' specified in '%s' tool.\n", ink, tool_id);
// 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");
if (it_controller == m_controllers.end())
throw base::Exception("Invalid controller '%s' specified in '%s' tool.\n", controller, tool_id);
// 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");
if (it_pointshaper == m_pointshapers.end())
throw base::Exception("Invalid point-shape '%s' specified in '%s' tool.\n", pointshape, tool_id);
// 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");
if (it_intertwiner == m_intertwiners.end())
throw base::Exception("Invalid intertwiner '%s' specified in '%s' tool.\n", intertwine, tool_id);
// Trace policy
ToolTracePolicy tracepolicy_value = TOOL_TRACE_POLICY_LAST;
TracePolicy tracepolicy_value = TracePolicyLast;
if (tracepolicy) {
if (strcmp(tracepolicy, "accumulative") == 0)
tracepolicy_value = TOOL_TRACE_POLICY_ACCUMULATE;
tracepolicy_value = TracePolicyAccumulate;
else if (strcmp(tracepolicy, "last") == 0)
tracepolicy_value = TOOL_TRACE_POLICY_LAST;
tracepolicy_value = TracePolicyLast;
else if (strcmp(tracepolicy, "overlap") == 0)
tracepolicy_value = TOOL_TRACE_POLICY_OVERLAP;
tracepolicy_value = TracePolicyOverlap;
else
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
*/
#ifndef TOOLS_TOOLBOX_H_INCLUDED
#define TOOLS_TOOLBOX_H_INCLUDED
#ifndef TOOLS_TOOL_BOX_H_INCLUDED
#define TOOLS_TOOL_BOX_H_INCLUDED
#include <string>
#include <list>
#include <map>
#include "tools/tool.h"
class TiXmlElement;
namespace tools {
typedef std::list<Tool*> ToolList;
typedef ToolList::iterator ToolIterator;
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
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:
ToolBox();
~ToolBox();
@ -61,8 +56,17 @@ public:
private:
void loadTools();
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 "raster/algo.h"
#include "raster/image.h"
#include "tools/tool.h"
#include "util/render.h"
#include "tools/tool_loop_manager.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 tools;
//////////////////////////////////////////////////////////////////////
// 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)
ToolLoopManager::ToolLoopManager(ToolLoop* toolLoop)
: m_toolLoop(toolLoop)
{
}
@ -115,6 +42,11 @@ ToolLoopManager::~ToolLoopManager()
delete m_toolLoop;
}
bool ToolLoopManager::isCanceled() const
{
return m_toolLoop->isCanceled();
}
void ToolLoopManager::prepareLoop(const Pointer& pointer)
{
// 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
std::vector<Point> points_to_interwine;
Points points_to_interwine;
if (!last_step)
m_toolLoop->getController()->getPointsToInterwine(m_points, points_to_interwine);
else
@ -214,18 +146,18 @@ void ToolLoopManager::doLoopStep(bool last_step)
switch (m_toolLoop->getTracePolicy()) {
case TOOL_TRACE_POLICY_ACCUMULATE:
case TracePolicyAccumulate:
// Do nothing. We accumulate traces in the destination image.
break;
case TOOL_TRACE_POLICY_LAST:
case TracePolicyLast:
// Copy source to destination (reset the previous trace). Useful
// for tools like Line and Ellipse tools (we kept the last trace only).
image_clear(m_toolLoop->getDstImage(), 0);
image_copy(m_toolLoop->getDstImage(), m_toolLoop->getSrcImage(), 0, 0);
break;
case TOOL_TRACE_POLICY_OVERLAP:
case TracePolicyOverlap:
// Copy destination to source (yes, destination to source). In
// this way each new trace overlaps the previous one.
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);
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);
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);
}
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;
calculateMinMax(points, minpt, maxpt);
@ -295,7 +227,7 @@ void ToolLoopManager::calculateDirtyArea(IToolLoop* loop, const std::vector<Poin
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);

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

View File

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

View File

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

View File

@ -167,10 +167,10 @@ StatusBar::~StatusBar()
void StatusBar::onCurrentToolChange()
{
if (isVisible()) {
Tool* currentTool = UIContext::instance()->getSettings()->getCurrentTool();
tools::Tool* currentTool = UIContext::instance()->getSettings()->getCurrentTool();
if (currentTool) {
this->showTool(500, currentTool);
this->setTextf("%s Selected", currentTool->getText().c_str());
showTool(500, currentTool);
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);

View File

@ -32,7 +32,8 @@ class ColorButton;
class Frame;
class Slider;
class StatusBar;
class Tool;
namespace tools { class Tool; }
class Progress
{
@ -61,7 +62,7 @@ public:
bool setStatusText(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 showTool(int msecs, Tool* tool);
void showTool(int msecs, tools::Tool* tool);
void showMovePixelsOptions();
void hideMovePixelsOptions();
@ -88,7 +89,7 @@ private:
State m_state;
// Showing a tool
Tool* m_tool;
tools::Tool* m_tool;
// Showing a color
Color m_color;

View File

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

View File

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