mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-31 00:32:48 +00:00
Add pixel-perfect drawing mode for freehand tools (issue 315)
* Added new app::tools::IntertwineAsPixelPerfect intertwiner * Added app::tools::FreehandAlgorithm enum * Added app::tools::WellKnownIntertwiners constants
This commit is contained in:
parent
f19aae9232
commit
1554875618
31
src/app/settings/freehand_algorithm.h
Normal file
31
src/app/settings/freehand_algorithm.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* Aseprite
|
||||||
|
* Copyright (C) 2001-2013 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 APP_SETTINGS_FREEHAND_ALGORITHM_H_INCLUDED
|
||||||
|
#define APP_SETTINGS_FREEHAND_ALGORITHM_H_INCLUDED
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
enum FreehandAlgorithm {
|
||||||
|
kDefaultFreehandAlgorithm,
|
||||||
|
kPixelPerfectFreehandAlgorithm,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace app
|
||||||
|
|
||||||
|
#endif // APP_SETTINGS_FREEHAND_ALGORITHM_H_INCLUDED
|
@ -41,4 +41,4 @@ namespace app {
|
|||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
|
||||||
#endif // SETTINGS_INK_TYPE_H_INCLUDED
|
#endif // APP_SETTINGS_INK_TYPE_H_INCLUDED
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define APP_SETTINGS_SETTINGS_H_INCLUDED
|
#define APP_SETTINGS_SETTINGS_H_INCLUDED
|
||||||
|
|
||||||
#include "app/color.h"
|
#include "app/color.h"
|
||||||
|
#include "app/settings/freehand_algorithm.h"
|
||||||
#include "app/settings/ink_type.h"
|
#include "app/settings/ink_type.h"
|
||||||
#include "app/settings/rotation_algorithm.h"
|
#include "app/settings/rotation_algorithm.h"
|
||||||
#include "gfx/point.h"
|
#include "gfx/point.h"
|
||||||
@ -91,6 +92,7 @@ namespace app {
|
|||||||
virtual int getSprayWidth() = 0;
|
virtual int getSprayWidth() = 0;
|
||||||
virtual int getSpraySpeed() = 0;
|
virtual int getSpraySpeed() = 0;
|
||||||
virtual InkType getInkType() = 0;
|
virtual InkType getInkType() = 0;
|
||||||
|
virtual FreehandAlgorithm getFreehandAlgorithm() = 0;
|
||||||
|
|
||||||
virtual void setOpacity(int opacity) = 0;
|
virtual void setOpacity(int opacity) = 0;
|
||||||
virtual void setTolerance(int tolerance) = 0;
|
virtual void setTolerance(int tolerance) = 0;
|
||||||
@ -99,6 +101,7 @@ namespace app {
|
|||||||
virtual void setSprayWidth(int width) = 0;
|
virtual void setSprayWidth(int width) = 0;
|
||||||
virtual void setSpraySpeed(int speed) = 0;
|
virtual void setSpraySpeed(int speed) = 0;
|
||||||
virtual void setInkType(InkType inkType) = 0;
|
virtual void setInkType(InkType inkType) = 0;
|
||||||
|
virtual void setFreehandAlgorithm(FreehandAlgorithm algorithm) = 0;
|
||||||
|
|
||||||
virtual void addObserver(ToolSettingsObserver* observer) = 0;
|
virtual void addObserver(ToolSettingsObserver* observer) = 0;
|
||||||
virtual void removeObserver(ToolSettingsObserver* observer) = 0;
|
virtual void removeObserver(ToolSettingsObserver* observer) = 0;
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define APP_SETTINGS_SETTINGS_OBSERVERS_H_INCLUDED
|
#define APP_SETTINGS_SETTINGS_OBSERVERS_H_INCLUDED
|
||||||
|
|
||||||
#include "app/color.h"
|
#include "app/color.h"
|
||||||
|
#include "app/settings/freehand_algorithm.h"
|
||||||
#include "app/settings/ink_type.h"
|
#include "app/settings/ink_type.h"
|
||||||
#include "app/settings/rotation_algorithm.h"
|
#include "app/settings/rotation_algorithm.h"
|
||||||
#include "raster/pen_type.h"
|
#include "raster/pen_type.h"
|
||||||
@ -51,6 +52,7 @@ namespace app {
|
|||||||
virtual void onSetSprayWidth(int newSprayWidth) {}
|
virtual void onSetSprayWidth(int newSprayWidth) {}
|
||||||
virtual void onSetSpraySpeed(int newSpraySpeed) {}
|
virtual void onSetSpraySpeed(int newSpraySpeed) {}
|
||||||
virtual void onSetInkType(InkType newInkType) {}
|
virtual void onSetInkType(InkType newInkType) {}
|
||||||
|
virtual void onSetFreehandAlgorithm(FreehandAlgorithm algorithm) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SelectionSettingsObserver {
|
class SelectionSettingsObserver {
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "app/color_swatches.h"
|
#include "app/color_swatches.h"
|
||||||
#include "app/ini_file.h"
|
#include "app/ini_file.h"
|
||||||
#include "app/settings/document_settings.h"
|
#include "app/settings/document_settings.h"
|
||||||
|
#include "app/tools/controller.h"
|
||||||
#include "app/tools/point_shape.h"
|
#include "app/tools/point_shape.h"
|
||||||
#include "app/tools/tool.h"
|
#include "app/tools/tool.h"
|
||||||
#include "app/tools/tool_box.h"
|
#include "app/tools/tool_box.h"
|
||||||
@ -537,6 +538,7 @@ class UIToolSettingsImpl
|
|||||||
int m_spray_width;
|
int m_spray_width;
|
||||||
int m_spray_speed;
|
int m_spray_speed;
|
||||||
InkType m_inkType;
|
InkType m_inkType;
|
||||||
|
FreehandAlgorithm m_freehandAlgorithm;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -554,6 +556,7 @@ public:
|
|||||||
m_spray_width = 16;
|
m_spray_width = 16;
|
||||||
m_spray_speed = 32;
|
m_spray_speed = 32;
|
||||||
m_inkType = (InkType)get_config_int(cfg_section.c_str(), "InkType", (int)kDefaultInk);
|
m_inkType = (InkType)get_config_int(cfg_section.c_str(), "InkType", (int)kDefaultInk);
|
||||||
|
m_freehandAlgorithm = kDefaultFreehandAlgorithm;
|
||||||
|
|
||||||
m_pen.enableSignals(false);
|
m_pen.enableSignals(false);
|
||||||
m_pen.setType((PenType)get_config_int(cfg_section.c_str(), "PenType", (int)PEN_TYPE_CIRCLE));
|
m_pen.setType((PenType)get_config_int(cfg_section.c_str(), "PenType", (int)PEN_TYPE_CIRCLE));
|
||||||
@ -566,6 +569,12 @@ public:
|
|||||||
m_spray_width = get_config_int(cfg_section.c_str(), "SprayWidth", m_spray_width);
|
m_spray_width = get_config_int(cfg_section.c_str(), "SprayWidth", m_spray_width);
|
||||||
m_spray_speed = get_config_int(cfg_section.c_str(), "SpraySpeed", m_spray_speed);
|
m_spray_speed = get_config_int(cfg_section.c_str(), "SpraySpeed", m_spray_speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_tool->getController(0)->isFreehand() ||
|
||||||
|
m_tool->getController(1)->isFreehand()) {
|
||||||
|
m_freehandAlgorithm = (FreehandAlgorithm)get_config_int(cfg_section.c_str(), "FreehandAlgorithm", (int)kDefaultFreehandAlgorithm);
|
||||||
|
setFreehandAlgorithm(m_freehandAlgorithm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~UIToolSettingsImpl()
|
~UIToolSettingsImpl()
|
||||||
@ -586,6 +595,11 @@ public:
|
|||||||
set_config_int(cfg_section.c_str(), "SpraySpeed", m_spray_speed);
|
set_config_int(cfg_section.c_str(), "SpraySpeed", m_spray_speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_tool->getController(0)->isFreehand() ||
|
||||||
|
m_tool->getController(1)->isFreehand()) {
|
||||||
|
set_config_int(cfg_section.c_str(), "FreehandAlgorithm", m_freehandAlgorithm);
|
||||||
|
}
|
||||||
|
|
||||||
set_config_bool(cfg_section.c_str(), "PreviewFilled", m_previewFilled);
|
set_config_bool(cfg_section.c_str(), "PreviewFilled", m_previewFilled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,6 +612,7 @@ public:
|
|||||||
int getSprayWidth() OVERRIDE { return m_spray_width; }
|
int getSprayWidth() OVERRIDE { return m_spray_width; }
|
||||||
int getSpraySpeed() OVERRIDE { return m_spray_speed; }
|
int getSpraySpeed() OVERRIDE { return m_spray_speed; }
|
||||||
InkType getInkType() OVERRIDE { return m_inkType; }
|
InkType getInkType() OVERRIDE { return m_inkType; }
|
||||||
|
FreehandAlgorithm getFreehandAlgorithm() OVERRIDE { return m_freehandAlgorithm; }
|
||||||
|
|
||||||
void setOpacity(int opacity) OVERRIDE { m_opacity = opacity; }
|
void setOpacity(int opacity) OVERRIDE { m_opacity = opacity; }
|
||||||
void setTolerance(int tolerance) OVERRIDE { m_tolerance = tolerance; }
|
void setTolerance(int tolerance) OVERRIDE { m_tolerance = tolerance; }
|
||||||
@ -606,6 +621,21 @@ public:
|
|||||||
void setSprayWidth(int width) OVERRIDE { m_spray_width = width; }
|
void setSprayWidth(int width) OVERRIDE { m_spray_width = width; }
|
||||||
void setSpraySpeed(int speed) OVERRIDE { m_spray_speed = speed; }
|
void setSpraySpeed(int speed) OVERRIDE { m_spray_speed = speed; }
|
||||||
void setInkType(InkType inkType) OVERRIDE { m_inkType = inkType; }
|
void setInkType(InkType inkType) OVERRIDE { m_inkType = inkType; }
|
||||||
|
void setFreehandAlgorithm(FreehandAlgorithm algorithm) OVERRIDE {
|
||||||
|
m_freehandAlgorithm = algorithm;
|
||||||
|
|
||||||
|
tools::ToolBox* toolBox = App::instance()->getToolBox();
|
||||||
|
for (int i=0; i<2; ++i) {
|
||||||
|
if (algorithm == kPixelPerfectFreehandAlgorithm) {
|
||||||
|
m_tool->setIntertwine(i, toolBox->getIntertwinerById(tools::WellKnownIntertwiners::AsPixelPerfect));
|
||||||
|
m_tool->setTracePolicy(i, tools::TracePolicyLast);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_tool->setIntertwine(i, toolBox->getIntertwinerById(tools::WellKnownIntertwiners::AsLines));
|
||||||
|
m_tool->setTracePolicy(i, tools::TracePolicyAccumulate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void addObserver(ToolSettingsObserver* observer) OVERRIDE {
|
void addObserver(ToolSettingsObserver* observer) OVERRIDE {
|
||||||
base::Observable<ToolSettingsObserver>::addObserver(observer);
|
base::Observable<ToolSettingsObserver>::addObserver(observer);
|
||||||
|
@ -35,7 +35,9 @@ namespace app {
|
|||||||
typedef std::vector<gfx::Point> Points;
|
typedef std::vector<gfx::Point> Points;
|
||||||
|
|
||||||
virtual ~Controller() { }
|
virtual ~Controller() { }
|
||||||
|
|
||||||
virtual bool canSnapToGrid() { return true; }
|
virtual bool canSnapToGrid() { return true; }
|
||||||
|
virtual bool isFreehand() { return false; }
|
||||||
|
|
||||||
// Called when the user starts drawing and each time a new button is
|
// Called when the user starts drawing and each time a new button is
|
||||||
// pressed. The controller could be sure that this method is called
|
// pressed. The controller could be sure that this method is called
|
||||||
|
@ -31,6 +31,10 @@ using namespace gfx;
|
|||||||
// Controls clicks for tools like pencil
|
// Controls clicks for tools like pencil
|
||||||
class FreehandController : public Controller {
|
class FreehandController : public Controller {
|
||||||
public:
|
public:
|
||||||
|
bool isFreehand()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
void pressButton(Points& points, const Point& point)
|
void pressButton(Points& points, const Point& point)
|
||||||
{
|
{
|
||||||
points.push_back(point);
|
points.push_back(point);
|
||||||
|
@ -33,6 +33,7 @@ namespace app {
|
|||||||
|
|
||||||
virtual ~Intertwine() { }
|
virtual ~Intertwine() { }
|
||||||
virtual bool snapByAngle() { return false; }
|
virtual bool snapByAngle() { return false; }
|
||||||
|
virtual void prepareIntertwine() { }
|
||||||
virtual void joinPoints(ToolLoop* loop, const Points& points) = 0;
|
virtual void joinPoints(ToolLoop* loop, const Points& points) = 0;
|
||||||
virtual void fillPoints(ToolLoop* loop, const Points& points) = 0;
|
virtual void fillPoints(ToolLoop* loop, const Points& points) = 0;
|
||||||
|
|
||||||
|
@ -220,5 +220,80 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IntertwineAsPixelPerfect : public Intertwine {
|
||||||
|
struct PPData {
|
||||||
|
Points& pts;
|
||||||
|
ToolLoop* loop;
|
||||||
|
PPData(Points& pts, ToolLoop* loop) : pts(pts), loop(loop) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void pixelPerfectLine(int x, int y, PPData* data)
|
||||||
|
{
|
||||||
|
gfx::Point newPoint(x, y);
|
||||||
|
|
||||||
|
if (data->pts.empty()
|
||||||
|
|| data->pts[data->pts.size()-1] != newPoint) {
|
||||||
|
data->pts.push_back(newPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Points m_pts;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void prepareIntertwine() OVERRIDE {
|
||||||
|
m_pts.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void joinPoints(ToolLoop* loop, const Points& points) OVERRIDE {
|
||||||
|
if (points.size() == 0)
|
||||||
|
return;
|
||||||
|
else if (m_pts.empty() && points.size() == 1) {
|
||||||
|
m_pts = points;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PPData data(m_pts, loop);
|
||||||
|
|
||||||
|
for (size_t c=0; c+1<points.size(); ++c) {
|
||||||
|
int x1 = points[c].x;
|
||||||
|
int y1 = points[c].y;
|
||||||
|
int x2 = points[c+1].x;
|
||||||
|
int y2 = points[c+1].y;
|
||||||
|
|
||||||
|
algo_line(x1, y1, x2, y2,
|
||||||
|
(void*)&data,
|
||||||
|
(AlgoPixel)&IntertwineAsPixelPerfect::pixelPerfectLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t c=0; c<m_pts.size(); ++c) {
|
||||||
|
// We ignore a pixel that is between other two pixels in the
|
||||||
|
// corner of a L-like shape.
|
||||||
|
if (c > 0 && c+1 < m_pts.size()
|
||||||
|
&& (m_pts[c-1].x == m_pts[c].x || m_pts[c-1].y == m_pts[c].y)
|
||||||
|
&& (m_pts[c+1].x == m_pts[c].x || m_pts[c+1].y == m_pts[c].y)
|
||||||
|
&& m_pts[c-1].x != m_pts[c+1].x
|
||||||
|
&& m_pts[c-1].y != m_pts[c+1].y) {
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
|
||||||
|
doPointshapePoint(m_pts[c].x, m_pts[c].y, loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fillPoints(ToolLoop* loop, const Points& points)
|
||||||
|
{
|
||||||
|
if (points.size() < 3) {
|
||||||
|
joinPoints(loop, points);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contour
|
||||||
|
joinPoints(loop, points);
|
||||||
|
|
||||||
|
// Fill content
|
||||||
|
algo_polygon(points.size(), (const int*)&points[0], loop, (AlgoHLine)doPointshapeHline);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace tools
|
} // namespace tools
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -69,6 +69,13 @@ const char* WellKnownInks::Move = "move";
|
|||||||
const char* WellKnownInks::Blur = "blur";
|
const char* WellKnownInks::Blur = "blur";
|
||||||
const char* WellKnownInks::Jumble = "jumble";
|
const char* WellKnownInks::Jumble = "jumble";
|
||||||
|
|
||||||
|
const char* WellKnownIntertwiners::None = "none";
|
||||||
|
const char* WellKnownIntertwiners::AsLines = "as_lines";
|
||||||
|
const char* WellKnownIntertwiners::AsRectangles = "as_rectangles";
|
||||||
|
const char* WellKnownIntertwiners::AsEllipses = "as_ellipses";
|
||||||
|
const char* WellKnownIntertwiners::AsBezier = "as_bezier";
|
||||||
|
const char* WellKnownIntertwiners::AsPixelPerfect = "as_pixel_perfect";
|
||||||
|
|
||||||
ToolBox::ToolBox()
|
ToolBox::ToolBox()
|
||||||
{
|
{
|
||||||
PRINTF("Toolbox module: installing\n");
|
PRINTF("Toolbox module: installing\n");
|
||||||
@ -102,11 +109,12 @@ ToolBox::ToolBox()
|
|||||||
m_pointshapers["floodfill"] = new FloodFillPointShape();
|
m_pointshapers["floodfill"] = new FloodFillPointShape();
|
||||||
m_pointshapers["spray"] = new SprayPointShape();
|
m_pointshapers["spray"] = new SprayPointShape();
|
||||||
|
|
||||||
m_intertwiners["none"] = new IntertwineNone();
|
m_intertwiners[WellKnownIntertwiners::None] = new IntertwineNone();
|
||||||
m_intertwiners["as_lines"] = new IntertwineAsLines();
|
m_intertwiners[WellKnownIntertwiners::AsLines] = new IntertwineAsLines();
|
||||||
m_intertwiners["as_rectangles"] = new IntertwineAsRectangles();
|
m_intertwiners[WellKnownIntertwiners::AsRectangles] = new IntertwineAsRectangles();
|
||||||
m_intertwiners["as_ellipses"] = new IntertwineAsEllipses();
|
m_intertwiners[WellKnownIntertwiners::AsEllipses] = new IntertwineAsEllipses();
|
||||||
m_intertwiners["as_bezier"] = new IntertwineAsBezier();
|
m_intertwiners[WellKnownIntertwiners::AsBezier] = new IntertwineAsBezier();
|
||||||
|
m_intertwiners[WellKnownIntertwiners::AsPixelPerfect] = new IntertwineAsPixelPerfect();
|
||||||
|
|
||||||
loadTools();
|
loadTools();
|
||||||
|
|
||||||
@ -152,9 +160,14 @@ Ink* ToolBox::getInkById(const std::string& id)
|
|||||||
return m_inks[id];
|
return m_inks[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Intertwine* ToolBox::getIntertwinerById(const std::string& id)
|
||||||
|
{
|
||||||
|
return m_intertwiners[id];
|
||||||
|
}
|
||||||
|
|
||||||
void ToolBox::loadTools()
|
void ToolBox::loadTools()
|
||||||
{
|
{
|
||||||
PRINTF("Loading ASEPRITE tools\n");
|
PRINTF("Loading Aseprite tools\n");
|
||||||
|
|
||||||
XmlDocumentRef doc(GuiXml::instance()->doc());
|
XmlDocumentRef doc(GuiXml::instance()->doc());
|
||||||
TiXmlHandle handle(doc);
|
TiXmlHandle handle(doc);
|
||||||
|
@ -53,6 +53,15 @@ namespace app {
|
|||||||
extern const char* Jumble;
|
extern const char* Jumble;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace WellKnownIntertwiners {
|
||||||
|
extern const char* None;
|
||||||
|
extern const char* AsLines;
|
||||||
|
extern const char* AsRectangles;
|
||||||
|
extern const char* AsEllipses;
|
||||||
|
extern const char* AsBezier;
|
||||||
|
extern const char* AsPixelPerfect;
|
||||||
|
};
|
||||||
|
|
||||||
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;
|
||||||
@ -75,6 +84,7 @@ namespace app {
|
|||||||
|
|
||||||
Tool* getToolById(const std::string& id);
|
Tool* getToolById(const std::string& id);
|
||||||
Ink* getInkById(const std::string& id);
|
Ink* getInkById(const std::string& id);
|
||||||
|
Intertwine* getIntertwinerById(const std::string& id);
|
||||||
int getGroupsCount() const { return m_groups.size(); }
|
int getGroupsCount() const { return m_groups.size(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -67,6 +67,7 @@ void ToolLoopManager::prepareLoop(const Pointer& pointer)
|
|||||||
|
|
||||||
// Prepare the ink
|
// Prepare the ink
|
||||||
m_toolLoop->getInk()->prepareInk(m_toolLoop);
|
m_toolLoop->getInk()->prepareInk(m_toolLoop);
|
||||||
|
m_toolLoop->getIntertwine()->prepareIntertwine();
|
||||||
|
|
||||||
// Prepare preview image (the destination image will be our preview
|
// Prepare preview image (the destination image will be our preview
|
||||||
// in the tool-loop time, so we can see what we are drawing)
|
// in the tool-loop time, so we can see what we are drawing)
|
||||||
|
@ -27,9 +27,11 @@
|
|||||||
#include "app/settings/ink_type.h"
|
#include "app/settings/ink_type.h"
|
||||||
#include "app/settings/settings.h"
|
#include "app/settings/settings.h"
|
||||||
#include "app/settings/settings_observers.h"
|
#include "app/settings/settings_observers.h"
|
||||||
|
#include "app/tools/controller.h"
|
||||||
#include "app/tools/ink.h"
|
#include "app/tools/ink.h"
|
||||||
#include "app/tools/point_shape.h"
|
#include "app/tools/point_shape.h"
|
||||||
#include "app/tools/tool.h"
|
#include "app/tools/tool.h"
|
||||||
|
#include "app/tools/tool_box.h"
|
||||||
#include "app/ui/button_set.h"
|
#include "app/ui/button_set.h"
|
||||||
#include "app/ui/color_button.h"
|
#include "app/ui/color_button.h"
|
||||||
#include "app/ui/skin/skin_theme.h"
|
#include "app/ui/skin/skin_theme.h"
|
||||||
@ -387,6 +389,24 @@ private:
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ContextBar::FreehandAlgorithmField : public CheckBox
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FreehandAlgorithmField() : CheckBox("Pixel-perfect") {
|
||||||
|
}
|
||||||
|
|
||||||
|
void onClick(Event& ev) OVERRIDE {
|
||||||
|
CheckBox::onClick(ev);
|
||||||
|
|
||||||
|
ISettings* settings = UIContext::instance()->getSettings();
|
||||||
|
Tool* currentTool = settings->getCurrentTool();
|
||||||
|
settings->getToolSettings(currentTool)
|
||||||
|
->setFreehandAlgorithm(isSelected() ?
|
||||||
|
kPixelPerfectFreehandAlgorithm:
|
||||||
|
kDefaultFreehandAlgorithm);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ContextBar::ContextBar()
|
ContextBar::ContextBar()
|
||||||
: Box(JI_HORIZONTAL)
|
: Box(JI_HORIZONTAL)
|
||||||
{
|
{
|
||||||
@ -412,6 +432,9 @@ ContextBar::ContextBar()
|
|||||||
// addChild(new InkShadeField());
|
// addChild(new InkShadeField());
|
||||||
// addChild(new InkSelectionField());
|
// addChild(new InkSelectionField());
|
||||||
|
|
||||||
|
addChild(m_freehandBox = new HBox());
|
||||||
|
m_freehandBox->addChild(m_freehandAlgo = new FreehandAlgorithmField());
|
||||||
|
|
||||||
addChild(m_sprayBox = new HBox());
|
addChild(m_sprayBox = new HBox());
|
||||||
m_sprayBox->addChild(new Label("Spray:"));
|
m_sprayBox->addChild(new Label("Spray:"));
|
||||||
m_sprayBox->addChild(m_sprayWidth = new SprayWidthField());
|
m_sprayBox->addChild(m_sprayWidth = new SprayWidthField());
|
||||||
@ -488,6 +511,8 @@ void ContextBar::onCurrentToolChange()
|
|||||||
m_inkType->setInkType(toolSettings->getInkType());
|
m_inkType->setInkType(toolSettings->getInkType());
|
||||||
m_inkOpacity->setTextf("%d", toolSettings->getOpacity());
|
m_inkOpacity->setTextf("%d", toolSettings->getOpacity());
|
||||||
|
|
||||||
|
m_freehandAlgo->setSelected(toolSettings->getFreehandAlgorithm() == kPixelPerfectFreehandAlgorithm);
|
||||||
|
|
||||||
m_sprayWidth->setValue(toolSettings->getSprayWidth());
|
m_sprayWidth->setValue(toolSettings->getSprayWidth());
|
||||||
m_spraySpeed->setValue(toolSettings->getSpraySpeed());
|
m_spraySpeed->setValue(toolSettings->getSpraySpeed());
|
||||||
|
|
||||||
@ -512,6 +537,10 @@ void ContextBar::onCurrentToolChange()
|
|||||||
bool hasSelectOptions = (currentTool->getInk(0)->isSelection() ||
|
bool hasSelectOptions = (currentTool->getInk(0)->isSelection() ||
|
||||||
currentTool->getInk(1)->isSelection());
|
currentTool->getInk(1)->isSelection());
|
||||||
|
|
||||||
|
bool isFreehand =
|
||||||
|
(currentTool->getController(0)->isFreehand() ||
|
||||||
|
currentTool->getController(1)->isFreehand());
|
||||||
|
|
||||||
// Show/Hide fields
|
// Show/Hide fields
|
||||||
m_brushLabel->setVisible(hasOpacity);
|
m_brushLabel->setVisible(hasOpacity);
|
||||||
m_brushType->setVisible(hasOpacity);
|
m_brushType->setVisible(hasOpacity);
|
||||||
@ -521,6 +550,7 @@ void ContextBar::onCurrentToolChange()
|
|||||||
m_inkLabel->setVisible(hasInk);
|
m_inkLabel->setVisible(hasInk);
|
||||||
m_inkType->setVisible(hasInk);
|
m_inkType->setVisible(hasInk);
|
||||||
m_inkOpacity->setVisible(hasOpacity);
|
m_inkOpacity->setVisible(hasOpacity);
|
||||||
|
m_freehandBox->setVisible(isFreehand);
|
||||||
m_toleranceLabel->setVisible(hasTolerance);
|
m_toleranceLabel->setVisible(hasTolerance);
|
||||||
m_tolerance->setVisible(hasTolerance);
|
m_tolerance->setVisible(hasTolerance);
|
||||||
m_sprayBox->setVisible(hasSprayOptions);
|
m_sprayBox->setVisible(hasSprayOptions);
|
||||||
|
@ -52,6 +52,7 @@ namespace app {
|
|||||||
class SpraySpeedField;
|
class SpraySpeedField;
|
||||||
class TransparentColorField;
|
class TransparentColorField;
|
||||||
class RotAlgorithmField;
|
class RotAlgorithmField;
|
||||||
|
class FreehandAlgorithmField;
|
||||||
|
|
||||||
ui::Label* m_brushLabel;
|
ui::Label* m_brushLabel;
|
||||||
BrushTypeField* m_brushType;
|
BrushTypeField* m_brushType;
|
||||||
@ -63,6 +64,8 @@ namespace app {
|
|||||||
InkTypeField* m_inkType;
|
InkTypeField* m_inkType;
|
||||||
ui::Label* m_opacityLabel;
|
ui::Label* m_opacityLabel;
|
||||||
InkOpacityField* m_inkOpacity;
|
InkOpacityField* m_inkOpacity;
|
||||||
|
ui::Box* m_freehandBox;
|
||||||
|
FreehandAlgorithmField* m_freehandAlgo;
|
||||||
ui::Box* m_sprayBox;
|
ui::Box* m_sprayBox;
|
||||||
SprayWidthField* m_sprayWidth;
|
SprayWidthField* m_sprayWidth;
|
||||||
SpraySpeedField* m_spraySpeed;
|
SpraySpeedField* m_spraySpeed;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user