summaryrefslogtreecommitdiffstats
path: root/src/ui/tools
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2014-04-01 17:00:00 +0000
committerJabiertxof <jtx@jtx.marker.es>2014-04-01 17:00:00 +0000
commit208ccdf9782984702f79b8ba416e67dd1e2c2dfa (patch)
tree79d15123aa526c49c6386db6245fbfc6b7a63eaf /src/ui/tools
parentupdate to trunk (diff)
parentpartial 2geom update: (diff)
downloadinkscape-208ccdf9782984702f79b8ba416e67dd1e2c2dfa.tar.gz
inkscape-208ccdf9782984702f79b8ba416e67dd1e2c2dfa.zip
update to trunk
(bzr r12588.1.32)
Diffstat (limited to 'src/ui/tools')
-rw-r--r--src/ui/tools/arc-tool.cpp51
-rw-r--r--src/ui/tools/arc-tool.h10
-rw-r--r--src/ui/tools/box3d-tool.cpp25
-rw-r--r--src/ui/tools/box3d-tool.h19
-rw-r--r--src/ui/tools/calligraphic-tool.cpp34
-rw-r--r--src/ui/tools/calligraphic-tool.h10
-rw-r--r--src/ui/tools/connector-tool.cpp765
-rw-r--r--src/ui/tools/connector-tool.h58
-rw-r--r--src/ui/tools/dropper-tool.cpp32
-rw-r--r--src/ui/tools/dropper-tool.h4
-rw-r--r--src/ui/tools/dynamic-base.cpp70
-rw-r--r--src/ui/tools/dynamic-base.h19
-rw-r--r--src/ui/tools/eraser-tool.cpp8
-rw-r--r--src/ui/tools/eraser-tool.h2
-rw-r--r--src/ui/tools/flood-tool.cpp27
-rw-r--r--src/ui/tools/freehand-base.cpp60
-rw-r--r--src/ui/tools/freehand-base.h29
-rw-r--r--src/ui/tools/gradient-tool.cpp32
-rw-r--r--src/ui/tools/lpe-tool.cpp22
-rw-r--r--src/ui/tools/measure-tool.cpp13
-rw-r--r--src/ui/tools/mesh-tool.cpp24
-rw-r--r--src/ui/tools/node-tool.cpp45
-rw-r--r--src/ui/tools/pen-tool.cpp1019
-rw-r--r--src/ui/tools/pen-tool.h53
-rw-r--r--src/ui/tools/pencil-tool.cpp646
-rw-r--r--src/ui/tools/pencil-tool.h22
-rw-r--r--src/ui/tools/rect-tool.cpp22
-rw-r--r--src/ui/tools/select-tool.cpp102
-rw-r--r--src/ui/tools/select-tool.h5
-rw-r--r--src/ui/tools/spiral-tool.cpp24
-rw-r--r--src/ui/tools/spray-tool.cpp225
-rw-r--r--src/ui/tools/spray-tool.h8
-rw-r--r--src/ui/tools/star-tool.cpp30
-rw-r--r--src/ui/tools/text-tool.cpp275
-rw-r--r--src/ui/tools/text-tool.h16
-rw-r--r--src/ui/tools/tool-base.cpp105
-rw-r--r--src/ui/tools/tool-base.h97
-rw-r--r--src/ui/tools/tweak-tool.cpp45
-rw-r--r--src/ui/tools/tweak-tool.h6
-rw-r--r--src/ui/tools/zoom-tool.cpp13
40 files changed, 2002 insertions, 2070 deletions
diff --git a/src/ui/tools/arc-tool.cpp b/src/ui/tools/arc-tool.cpp
index bb7dfa21c..43f8eb9e1 100644
--- a/src/ui/tools/arc-tool.cpp
+++ b/src/ui/tools/arc-tool.cpp
@@ -69,18 +69,10 @@ const std::string& ArcTool::getPrefsPath() {
const std::string ArcTool::prefsPath = "/tools/shapes/arc";
-ArcTool::ArcTool() : ToolBase() {
- this->cursor_shape = cursor_ellipse_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
- this->xp = 0;
- this->yp = 0;
- this->tolerance = 0;
- this->within_tolerance = false;
- this->item_to_select = NULL;
- //this->tool_url = "/tools/shapes/arc";
-
- this->arc = NULL;
+ArcTool::ArcTool()
+ : ToolBase(cursor_ellipse_xpm, 4, 4)
+ , arc(NULL)
+{
}
void ArcTool::finish() {
@@ -142,13 +134,10 @@ void ArcTool::setup() {
}
bool ArcTool::item_handler(SPItem* item, GdkEvent* event) {
- gint ret = FALSE;
-
switch (event->type) {
case GDK_BUTTON_PRESS:
if (event->button.button == 1 && !this->space_panning) {
Inkscape::setup_for_drag_start(desktop, this, event);
- ret = TRUE;
}
break;
// motion and release are always on root (why?)
@@ -156,13 +145,7 @@ bool ArcTool::item_handler(SPItem* item, GdkEvent* event) {
break;
}
-// if ((SP_EVENT_CONTEXT_CLASS(sp_arc_context_parent_class))->item_handler) {
-// ret = (SP_EVENT_CONTEXT_CLASS(sp_arc_context_parent_class))->item_handler(event_context, item, event);
-// }
- // CPPIFY: ret is overwritten...
- ret = ToolBase::item_handler(item, event);
-
- return ret;
+ return ToolBase::item_handler(item, event);
}
bool ArcTool::root_handler(GdkEvent* event) {
@@ -173,7 +156,7 @@ bool ArcTool::root_handler(GdkEvent* event) {
this->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
- gint ret = FALSE;
+ bool handled = false;
switch (event->type) {
case GDK_BUTTON_PRESS:
@@ -191,7 +174,7 @@ bool ArcTool::root_handler(GdkEvent* event) {
GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK,
NULL, event->button.time);
- ret = TRUE;
+ handled = true;
m.unSetup();
}
break;
@@ -214,8 +197,8 @@ bool ArcTool::root_handler(GdkEvent* event) {
gobble_motion_events(GDK_BUTTON1_MASK);
- ret = TRUE;
- } else if (!sp_event_context_knot_mouseover(this)){
+ handled = true;
+ } else if (!this->sp_event_context_knot_mouseover()){
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
@@ -249,7 +232,7 @@ bool ArcTool::root_handler(GdkEvent* event) {
this->xp = 0;
this->yp = 0;
this->item_to_select = NULL;
- ret = TRUE;
+ handled = true;
}
sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time);
break;
@@ -278,14 +261,14 @@ bool ArcTool::root_handler(GdkEvent* event) {
case GDK_KEY_KP_Down:
// prevent the zoom field from activation
if (!MOD__CTRL_ONLY(event))
- ret = TRUE;
+ handled = true;
break;
case GDK_KEY_x:
case GDK_KEY_X:
if (MOD__ALT_ONLY(event)) {
desktop->setToolboxFocusTo ("altx-arc");
- ret = TRUE;
+ handled = true;
}
break;
@@ -295,7 +278,7 @@ bool ArcTool::root_handler(GdkEvent* event) {
sp_event_context_discard_delayed_snap_event(this);
// if drawing, cancel, otherwise pass it up for deselecting
this->cancel();
- ret = TRUE;
+ handled = true;
}
break;
@@ -316,7 +299,7 @@ bool ArcTool::root_handler(GdkEvent* event) {
case GDK_KEY_Delete:
case GDK_KEY_KP_Delete:
case GDK_KEY_BackSpace:
- ret = this->deleteSelectedDrag(MOD__CTRL_ONLY(event));
+ handled = this->deleteSelectedDrag(MOD__CTRL_ONLY(event));
break;
default:
@@ -346,11 +329,11 @@ bool ArcTool::root_handler(GdkEvent* event) {
break;
}
- if (!ret) {
- ret = ToolBase::root_handler(event);
+ if (!handled) {
+ handled = ToolBase::root_handler(event);
}
- return ret;
+ return handled;
}
void ArcTool::drag(Geom::Point pt, guint state) {
diff --git a/src/ui/tools/arc-tool.h b/src/ui/tools/arc-tool.h
index eaa50f2b9..c4c67660d 100644
--- a/src/ui/tools/arc-tool.h
+++ b/src/ui/tools/arc-tool.h
@@ -16,12 +16,18 @@
*/
#include <stddef.h>
-#include <sigc++/connection.h>
#include <2geom/point.h>
+#include <sigc++/connection.h>
+
#include "ui/tools/tool-base.h"
-#include "sp-ellipse.h"
+class SPItem;
+class SPGenericEllipse;
+
+namespace Inkscape {
+ class Selection;
+}
#define SP_ARC_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::ArcTool*>((Inkscape::UI::Tools::ToolBase*)obj))
#define SP_IS_ARC_CONTEXT(obj) (dynamic_cast<const Inkscape::UI::Tools::ArcTool*>(const Inkscape::UI::Tools::ToolBase*(obj)) != NULL)
diff --git a/src/ui/tools/box3d-tool.cpp b/src/ui/tools/box3d-tool.cpp
index 2e345fef1..e00894d55 100644
--- a/src/ui/tools/box3d-tool.cpp
+++ b/src/ui/tools/box3d-tool.cpp
@@ -72,22 +72,13 @@ const std::string& Box3dTool::getPrefsPath() {
const std::string Box3dTool::prefsPath = "/tools/shapes/3dbox";
-Box3dTool::Box3dTool() : ToolBase() {
- this->cursor_shape = cursor_3dbox_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
- this->xp = 0;
- this->yp = 0;
- this->tolerance = 0;
- this->within_tolerance = false;
- this->item_to_select = NULL;
-
- this->box3d = NULL;
-
- this->ctrl_dragged = false;
- this->extruded = false;
-
- this->_vpdrag = NULL;
+Box3dTool::Box3dTool()
+ : ToolBase(cursor_3dbox_xpm, 4, 4)
+ , _vpdrag(NULL)
+ , box3d(NULL)
+ , ctrl_dragged(false)
+ , extruded(false)
+{
}
void Box3dTool::finish() {
@@ -322,7 +313,7 @@ bool Box3dTool::root_handler(GdkEvent* event) {
this->drag(event->motion.state);
ret = TRUE;
- } else if (!sp_event_context_knot_mouseover(this)) {
+ } else if (!this->sp_event_context_knot_mouseover()) {
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
diff --git a/src/ui/tools/box3d-tool.h b/src/ui/tools/box3d-tool.h
index 99bf99a7a..1dd6bb5f8 100644
--- a/src/ui/tools/box3d-tool.h
+++ b/src/ui/tools/box3d-tool.h
@@ -16,12 +16,25 @@
*/
#include <stddef.h>
-#include <sigc++/sigc++.h>
-#include "ui/tools/tool-base.h"
+
+#include <2geom/point.h>
+#include <sigc++/connection.h>
+
#include "proj_pt.h"
#include "vanishing-point.h"
-#include "box3d.h"
+#include "ui/tools/tool-base.h"
+
+class SPItem;
+class SPBox3D;
+
+namespace Box3D {
+ struct VPDrag;
+}
+
+namespace Inkscape {
+ class Selection;
+}
#define SP_BOX3D_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::Box3dTool*>((Inkscape::UI::Tools::ToolBase*)obj))
#define SP_IS_BOX3D_CONTEXT(obj) (dynamic_cast<const Inkscape::UI::Tools::Box3dTool*>((const Inkscape::UI::Tools::ToolBase*)obj) != NULL)
diff --git a/src/ui/tools/calligraphic-tool.cpp b/src/ui/tools/calligraphic-tool.cpp
index 2c5e6561c..64097e834 100644
--- a/src/ui/tools/calligraphic-tool.cpp
+++ b/src/ui/tools/calligraphic-tool.cpp
@@ -105,30 +105,24 @@ const std::string& CalligraphicTool::getPrefsPath() {
const std::string CalligraphicTool::prefsPath = "/tools/calligraphic";
-CalligraphicTool::CalligraphicTool() : DynamicBase() {
- this->cursor_shape = cursor_calligraphy_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
-
+CalligraphicTool::CalligraphicTool()
+ : DynamicBase(cursor_calligraphy_xpm, 4, 4)
+ , keep_selected(true)
+ , hatch_spacing(0)
+ , hatch_spacing_step(0)
+ , hatch_item(NULL)
+ , hatch_livarot_path(NULL)
+ , hatch_last_nearest(Geom::Point(0,0))
+ , hatch_last_pointer(Geom::Point(0,0))
+ , hatch_escaped(false)
+ , hatch_area(NULL)
+ , just_started_drawing(false)
+ , trace_bg(false)
+{
this->vel_thin = 0.1;
this->flatness = 0.9;
this->cap_rounding = 0.0;
-
this->abs_width = false;
- this->keep_selected = true;
-
- this->hatch_spacing = 0;
- this->hatch_spacing_step = 0;
-
- this->hatch_last_nearest = Geom::Point(0,0);
- this->hatch_last_pointer = Geom::Point(0,0);
- this->hatch_escaped = false;
- this->hatch_area = NULL;
- this->hatch_item = NULL;
- this->hatch_livarot_path = NULL;
-
- this->trace_bg = false;
- this->just_started_drawing = false;
}
CalligraphicTool::~CalligraphicTool() {
diff --git a/src/ui/tools/calligraphic-tool.h b/src/ui/tools/calligraphic-tool.h
index 926e9d126..83b4d73ff 100644
--- a/src/ui/tools/calligraphic-tool.h
+++ b/src/ui/tools/calligraphic-tool.h
@@ -18,8 +18,16 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#include <list>
+#include <string>
+
+#include <2geom/point.h>
+
#include "ui/tools/dynamic-base.h"
-#include "splivarot.h"
+
+class SPItem;
+class Path;
+struct SPCanvasItem;
#define DDC_MIN_PRESSURE 0.0
#define DDC_MAX_PRESSURE 1.0
diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp
index 62d52f6af..d1355e807 100644
--- a/src/ui/tools/connector-tool.cpp
+++ b/src/ui/tools/connector-tool.cpp
@@ -115,40 +115,19 @@ namespace Inkscape {
namespace UI {
namespace Tools {
-// Stuff borrowed from DrawContext
-static void spcc_connector_set_initial_point(ConnectorTool *cc, Geom::Point const p);
-static void spcc_connector_set_subsequent_point(ConnectorTool *cc, Geom::Point const p);
-static void spcc_connector_finish_segment(ConnectorTool *cc, Geom::Point p);
-static void spcc_reset_colors(ConnectorTool *cc);
-static void spcc_connector_finish(ConnectorTool *cc);
-static void spcc_concat_colors_and_flush(ConnectorTool *cc);
-static void spcc_flush_white(ConnectorTool *cc, SPCurve *gc);
-
-// Context event handlers
-static gint connector_handle_button_press(ConnectorTool *const cc, GdkEventButton const &bevent);
-static gint connector_handle_motion_notify(ConnectorTool *const cc, GdkEventMotion const &mevent);
-static gint connector_handle_button_release(ConnectorTool *const cc, GdkEventButton const &revent);
-static gint connector_handle_key_press(ConnectorTool *const cc, guint const keyval);
-
-static void cc_active_shape_add_knot(ConnectorTool *cc, SPItem* item);
-static void cc_set_active_shape(ConnectorTool *cc, SPItem *item);
static void cc_clear_active_knots(SPKnotList k);
-static void cc_clear_active_shape(ConnectorTool *cc);
-static void cc_set_active_conn(ConnectorTool *cc, SPItem *item);
-static void cc_clear_active_conn(ConnectorTool *cc);
-static bool conn_pt_handle_test(ConnectorTool *cc, Geom::Point& p, gchar **href);
-static void cc_select_handle(SPKnot* knot);
-static void cc_deselect_handle(SPKnot* knot);
-static bool cc_item_is_shape(SPItem *item);
-static void cc_connector_rerouting_finish(ConnectorTool *const cc,
- Geom::Point *const p);
static void shape_event_attr_deleted(Inkscape::XML::Node *repr,
Inkscape::XML::Node *child, Inkscape::XML::Node *ref, gpointer data);
+
static void shape_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
gchar const *old_value, gchar const *new_value, bool is_interactive,
gpointer data);
+static void cc_select_handle(SPKnot* knot);
+static void cc_deselect_handle(SPKnot* knot);
+static bool cc_item_is_shape(SPItem *item);
+
/*static Geom::Point connector_drag_origin_w(0, 0);
static bool connector_within_tolerance = false;*/
@@ -182,54 +161,39 @@ const std::string& ConnectorTool::getPrefsPath() {
const std::string ConnectorTool::prefsPath = "/tools/connector";
-ConnectorTool::ConnectorTool() : ToolBase() {
- this->red_curve = 0;
- this->isOrthogonal = false;
- this->c1 = 0;
- this->red_bpath = 0;
- this->green_curve = 0;
- this->selection = 0;
- this->cl0 = 0;
- this->cl1 = 0;
- this->c0 = 0;
-
- this->cursor_shape = cursor_connector_xpm;
- this->hot_x = 1;
- this->hot_y = 1;
- this->xp = 0;
- this->yp = 0;
-
- this->red_color = 0xff00007f;
-
- this->newconn = NULL;
- this->newConnRef = NULL;
- this->curvature = 0.0;
-
- this->sel_changed_connection = sigc::connection();
-
- this->active_shape = NULL;
- this->active_shape_repr = NULL;
- this->active_shape_layer_repr = NULL;
-
- this->active_conn = NULL;
- this->active_conn_repr = NULL;
-
- this->active_handle = NULL;
-
- this->selected_handle = NULL;
-
- this->clickeditem = NULL;
- this->clickedhandle = NULL;
-
+ConnectorTool::ConnectorTool()
+ : ToolBase(cursor_connector_xpm, 1, 1)
+ , selection(NULL)
+ , npoints(0)
+ , state(SP_CONNECTOR_CONTEXT_IDLE)
+ , red_bpath(NULL)
+ , red_curve(NULL)
+ , red_color(0xff00007f)
+ , green_curve(NULL)
+ , newconn(NULL)
+ , newConnRef(NULL)
+ , curvature(0.0)
+ , isOrthogonal(false)
+ , active_shape(NULL)
+ , active_shape_repr(NULL)
+ , active_shape_layer_repr(NULL)
+ , active_conn(NULL)
+ , active_conn_repr(NULL)
+ , active_handle(NULL)
+ , selected_handle(NULL)
+ , clickeditem(NULL)
+ , clickedhandle(NULL)
+ , shref(NULL)
+ , ehref(NULL)
+ , c0(NULL)
+ , c1(NULL)
+ , cl0(NULL)
+ , cl1(NULL)
+{
for (int i = 0; i < 2; ++i) {
this->endpt_handle[i] = NULL;
this->endpt_handler_id[i] = 0;
}
-
- this->shref = NULL;
- this->ehref = NULL;
- this->npoints = 0;
- this->state = SP_CONNECTOR_CONTEXT_IDLE;
}
ConnectorTool::~ConnectorTool() {
@@ -237,7 +201,8 @@ ConnectorTool::~ConnectorTool() {
for (int i = 0; i < 2; ++i) {
if (this->endpt_handle[1]) {
- g_object_unref(this->endpt_handle[i]);
+ //g_object_unref(this->endpt_handle[i]);
+ knot_unref(this->endpt_handle[i]);
this->endpt_handle[i] = NULL;
}
}
@@ -262,7 +227,7 @@ void ConnectorTool::setup() {
this->sel_changed_connection.disconnect();
this->sel_changed_connection = this->selection->connectChanged(
- sigc::mem_fun(this, &ConnectorTool::selection_changed)
+ sigc::mem_fun(this, &ConnectorTool::_selectionChanged)
);
/* Create red bpath */
@@ -279,7 +244,7 @@ void ConnectorTool::setup() {
// Notice the initial selection.
//cc_selection_changed(this->selection, (gpointer) this);
- this->selection_changed(this->selection);
+ this->_selectionChanged(this->selection);
this->within_tolerance = false;
@@ -308,7 +273,7 @@ void ConnectorTool::set(const Inkscape::Preferences::Entry& val) {
}
void ConnectorTool::finish() {
- spcc_connector_finish(this);
+ this->_finish();
this->state = SP_CONNECTOR_CONTEXT_IDLE;
ToolBase::finish();
@@ -317,8 +282,8 @@ void ConnectorTool::finish() {
this->selection = NULL;
}
- cc_clear_active_shape(this);
- cc_clear_active_conn(this);
+ this->cc_clear_active_shape();
+ this->cc_clear_active_conn();
// Restore the default event generating behaviour.
this->desktop->canvas->gen_all_enter_events = false;
@@ -327,28 +292,26 @@ void ConnectorTool::finish() {
//-----------------------------------------------------------------------------
-static void
-cc_clear_active_shape(ConnectorTool *cc)
-{
- if (cc->active_shape == NULL) {
+void ConnectorTool::cc_clear_active_shape() {
+ if (this->active_shape == NULL) {
return;
}
- g_assert( cc->active_shape_repr );
- g_assert( cc->active_shape_layer_repr );
+ g_assert( this->active_shape_repr );
+ g_assert( this->active_shape_layer_repr );
- cc->active_shape = NULL;
+ this->active_shape = NULL;
- if (cc->active_shape_repr) {
- sp_repr_remove_listener_by_data(cc->active_shape_repr, cc);
- Inkscape::GC::release(cc->active_shape_repr);
- cc->active_shape_repr = NULL;
+ if (this->active_shape_repr) {
+ sp_repr_remove_listener_by_data(this->active_shape_repr, this);
+ Inkscape::GC::release(this->active_shape_repr);
+ this->active_shape_repr = NULL;
- sp_repr_remove_listener_by_data(cc->active_shape_layer_repr, cc);
- Inkscape::GC::release(cc->active_shape_layer_repr);
- cc->active_shape_layer_repr = NULL;
+ sp_repr_remove_listener_by_data(this->active_shape_layer_repr, this);
+ Inkscape::GC::release(this->active_shape_layer_repr);
+ this->active_shape_layer_repr = NULL;
}
- cc_clear_active_knots(cc->knots);
+ cc_clear_active_knots(this->knots);
}
static void
@@ -357,43 +320,39 @@ cc_clear_active_knots(SPKnotList k)
// Hide the connection points if they exist.
if (k.size()) {
for (SPKnotList::iterator it = k.begin(); it != k.end(); ++it) {
- sp_knot_hide(it->first);
+ it->first->hide();
}
}
}
-static void
-cc_clear_active_conn(ConnectorTool *cc)
-{
- if (cc->active_conn == NULL) {
+void ConnectorTool::cc_clear_active_conn() {
+ if (this->active_conn == NULL) {
return;
}
- g_assert( cc->active_conn_repr );
+ g_assert( this->active_conn_repr );
- cc->active_conn = NULL;
+ this->active_conn = NULL;
- if (cc->active_conn_repr) {
- sp_repr_remove_listener_by_data(cc->active_conn_repr, cc);
- Inkscape::GC::release(cc->active_conn_repr);
- cc->active_conn_repr = NULL;
+ if (this->active_conn_repr) {
+ sp_repr_remove_listener_by_data(this->active_conn_repr, this);
+ Inkscape::GC::release(this->active_conn_repr);
+ this->active_conn_repr = NULL;
}
// Hide the endpoint handles.
for (int i = 0; i < 2; ++i) {
- if (cc->endpt_handle[i]) {
- sp_knot_hide(cc->endpt_handle[i]);
+ if (this->endpt_handle[i]) {
+ this->endpt_handle[i]->hide();
}
}
}
-static bool
-conn_pt_handle_test(ConnectorTool *cc, Geom::Point& p, gchar **href)
-{
- if (cc->active_handle && (cc->knots.find(cc->active_handle) != cc->knots.end()))
+bool ConnectorTool::_ptHandleTest(Geom::Point& p, gchar **href) {
+ if (this->active_handle && (this->knots.find(this->active_handle) != this->knots.end()))
{
- p = cc->active_handle->pos;
- *href = g_strdup_printf("#%s", cc->active_handle->owner->getId());
+ p = this->active_handle->pos;
+ *href = g_strdup_printf("#%s", this->active_handle->owner->getId());
return true;
}
*href = NULL;
@@ -407,7 +366,7 @@ cc_select_handle(SPKnot* knot)
knot->setSize(10);
knot->setAnchor(SP_ANCHOR_CENTER);
knot->setFill(0x0000ffff, 0x0000ffff, 0x0000ffff);
- sp_knot_update_ctrl(knot);
+ knot->updateCtrl();
}
static void
@@ -417,11 +376,11 @@ cc_deselect_handle(SPKnot* knot)
knot->setSize(8);
knot->setAnchor(SP_ANCHOR_CENTER);
knot->setFill(0xffffff00, 0xff0000ff, 0xff0000ff);
- sp_knot_update_ctrl(knot);
+ knot->updateCtrl();
}
bool ConnectorTool::item_handler(SPItem* item, GdkEvent* event) {
- gint ret = FALSE;
+ bool ret = false;
Geom::Point p(event->button.x, event->button.y);
@@ -429,7 +388,7 @@ bool ConnectorTool::item_handler(SPItem* item, GdkEvent* event) {
case GDK_BUTTON_RELEASE:
if (event->button.button == 1 && !this->space_panning) {
if ((this->state == SP_CONNECTOR_CONTEXT_DRAGGING) && this->within_tolerance) {
- spcc_reset_colors(this);
+ this->_resetColors();
this->state = SP_CONNECTOR_CONTEXT_IDLE;
}
@@ -450,21 +409,21 @@ bool ConnectorTool::item_handler(SPItem* item, GdkEvent* event) {
*/
if (item != this->active_shape && !cc_item_is_connector(item)) {
- cc_set_active_shape(this, item);
+ this->_setActiveShape(item);
}
}
- ret = TRUE;
+ ret = true;
}
break;
case GDK_ENTER_NOTIFY:
if (!this->selected_handle) {
if (cc_item_is_shape(item)) {
- cc_set_active_shape(this, item);
+ this->_setActiveShape(item);
}
- ret = TRUE;
+ ret = true;
}
break;
@@ -476,23 +435,23 @@ bool ConnectorTool::item_handler(SPItem* item, GdkEvent* event) {
}
bool ConnectorTool::root_handler(GdkEvent* event) {
- gint ret = FALSE;
+ bool ret = false;
switch (event->type) {
case GDK_BUTTON_PRESS:
- ret = connector_handle_button_press(this, event->button);
+ ret = this->_handleButtonPress(event->button);
break;
case GDK_MOTION_NOTIFY:
- ret = connector_handle_motion_notify(this, event->motion);
+ ret = this->_handleMotionNotify(event->motion);
break;
case GDK_BUTTON_RELEASE:
- ret = connector_handle_button_release(this, event->button);
+ ret = this->_handleButtonRelease(event->button);
break;
case GDK_KEY_PRESS:
- ret = connector_handle_key_press(this, get_group0_keyval (&event->key));
+ ret = this->_handleKeyPress(get_group0_keyval (&event->key));
break;
default:
@@ -507,83 +466,76 @@ bool ConnectorTool::root_handler(GdkEvent* event) {
}
-static gint
-connector_handle_button_press(ConnectorTool *const cc, GdkEventButton const &bevent)
-{
+bool ConnectorTool::_handleButtonPress(GdkEventButton const &bevent) {
Geom::Point const event_w(bevent.x, bevent.y);
/* Find desktop coordinates */
- Geom::Point p = cc->desktop->w2d(event_w);
- ToolBase *event_context = SP_EVENT_CONTEXT(cc);
-
- gint ret = FALSE;
+ Geom::Point p = this->desktop->w2d(event_w);
- if ( bevent.button == 1 && !event_context->space_panning ) {
+ bool ret = false;
- SPDesktop *desktop = cc->desktop;
-
- if (Inkscape::have_viable_layer(desktop, cc->message_context) == false) {
- return TRUE;
+ if ( bevent.button == 1 && !this->space_panning ) {
+ if (Inkscape::have_viable_layer(desktop, this->message_context) == false) {
+ return true;
}
- Geom::Point const event_w(bevent.x,
- bevent.y);
+ Geom::Point const event_w(bevent.x, bevent.y);
- cc->xp = bevent.x;
- cc->yp = bevent.y;
- cc->within_tolerance = true;
+ this->xp = bevent.x;
+ this->yp = bevent.y;
+ this->within_tolerance = true;
- Geom::Point const event_dt = cc->desktop->w2d(event_w);
+ Geom::Point const event_dt = this->desktop->w2d(event_w);
- SnapManager &m = cc->desktop->namedview->snap_manager;
+ SnapManager &m = this->desktop->namedview->snap_manager;
- switch (cc->state) {
+ switch (this->state) {
case SP_CONNECTOR_CONTEXT_STOP:
/* This is allowed, if we just canceled curve */
case SP_CONNECTOR_CONTEXT_IDLE:
{
- if ( cc->npoints == 0 ) {
- cc_clear_active_conn(cc);
+ if ( this->npoints == 0 ) {
+ this->cc_clear_active_conn();
- cc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating new connector"));
+ this->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating new connector"));
/* Set start anchor */
/* Create green anchor */
Geom::Point p = event_dt;
// Test whether we clicked on a connection point
- bool found = conn_pt_handle_test(cc, p, &cc->shref);
+ bool found = this->_ptHandleTest(p, &this->shref);
if (!found) {
// This is the first point, so just snap it to the grid
// as there's no other points to go off.
- m.setup(cc->desktop);
+ m.setup(this->desktop);
m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
m.unSetup();
}
- spcc_connector_set_initial_point(cc, p);
+ this->_setInitialPoint(p);
}
- cc->state = SP_CONNECTOR_CONTEXT_DRAGGING;
- ret = TRUE;
+ this->state = SP_CONNECTOR_CONTEXT_DRAGGING;
+ ret = true;
break;
}
case SP_CONNECTOR_CONTEXT_DRAGGING:
{
// This is the second click of a connector creation.
- m.setup(cc->desktop);
+ m.setup(this->desktop);
m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
m.unSetup();
- spcc_connector_set_subsequent_point(cc, p);
- spcc_connector_finish_segment(cc, p);
+ this->_setSubsequentPoint(p);
+ this->_finishSegment(p);
- conn_pt_handle_test(cc, p, &cc->ehref);
- if (cc->npoints != 0) {
- spcc_connector_finish(cc);
+ this->_ptHandleTest(p, &this->ehref);
+ if (this->npoints != 0) {
+ this->_finish();
}
- cc_set_active_conn(cc, cc->newconn);
- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
- ret = TRUE;
+ this->cc_set_active_conn(this->newconn);
+ this->state = SP_CONNECTOR_CONTEXT_IDLE;
+ ret = true;
break;
}
case SP_CONNECTOR_CONTEXT_CLOSE:
@@ -595,111 +547,106 @@ connector_handle_button_press(ConnectorTool *const cc, GdkEventButton const &bev
break;
}
} else if (bevent.button == 3) {
- if (cc->state == SP_CONNECTOR_CONTEXT_REROUTING) {
+ if (this->state == SP_CONNECTOR_CONTEXT_REROUTING) {
// A context menu is going to be triggered here,
// so end the rerouting operation.
- cc_connector_rerouting_finish(cc, &p);
+ this->_reroutingFinish(&p);
- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
+ this->state = SP_CONNECTOR_CONTEXT_IDLE;
// Don't set ret to TRUE, so we drop through to the
// parent handler which will open the context menu.
}
- else if (cc->npoints != 0) {
- spcc_connector_finish(cc);
- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
- ret = TRUE;
+ else if (this->npoints != 0) {
+ this->_finish();
+ this->state = SP_CONNECTOR_CONTEXT_IDLE;
+ ret = true;
}
}
return ret;
}
-static gint
-connector_handle_motion_notify(ConnectorTool *const cc, GdkEventMotion const &mevent)
-{
- gint ret = FALSE;
- ToolBase *event_context = SP_EVENT_CONTEXT(cc);
+bool ConnectorTool::_handleMotionNotify(GdkEventMotion const &mevent) {
+ bool ret = false;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- if (event_context->space_panning || mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) {
+ if (this->space_panning || mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) {
// allow middle-button scrolling
- return FALSE;
+ return false;
}
Geom::Point const event_w(mevent.x, mevent.y);
- if (cc->within_tolerance) {
- cc->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
- if ( ( abs( (gint) mevent.x - cc->xp ) < cc->tolerance ) &&
- ( abs( (gint) mevent.y - cc->yp ) < cc->tolerance ) ) {
- return FALSE; // Do not drag if we're within tolerance from origin.
+ if (this->within_tolerance) {
+ this->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
+ if ( ( abs( (gint) mevent.x - this->xp ) < this->tolerance ) &&
+ ( abs( (gint) mevent.y - this->yp ) < this->tolerance ) ) {
+ return false; // Do not drag if we're within tolerance from origin.
}
}
// Once the user has moved farther than tolerance from the original location
// (indicating they intend to move the object, not click), then always process
// the motion notify coordinates as given (no snapping back to origin)
- cc->within_tolerance = false;
-
- SPDesktop *const dt = cc->desktop;
+ this->within_tolerance = false;
/* Find desktop coordinates */
- Geom::Point p = dt->w2d(event_w);
+ Geom::Point p = desktop->w2d(event_w);
- SnapManager &m = dt->namedview->snap_manager;
+ SnapManager &m = desktop->namedview->snap_manager;
- switch (cc->state) {
+ switch (this->state) {
case SP_CONNECTOR_CONTEXT_DRAGGING:
{
gobble_motion_events(mevent.state);
// This is movement during a connector creation.
- if ( cc->npoints > 0 ) {
- m.setup(dt);
+ if ( this->npoints > 0 ) {
+ m.setup(desktop);
m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
m.unSetup();
- cc->selection->clear();
- spcc_connector_set_subsequent_point(cc, p);
- ret = TRUE;
+ this->selection->clear();
+ this->_setSubsequentPoint(p);
+ ret = true;
}
break;
}
case SP_CONNECTOR_CONTEXT_REROUTING:
{
gobble_motion_events(GDK_BUTTON1_MASK);
- g_assert( SP_IS_PATH(cc->clickeditem));
+ g_assert( SP_IS_PATH(this->clickeditem));
- m.setup(dt);
+ m.setup(desktop);
m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
m.unSetup();
// Update the hidden path
- Geom::Affine i2d ( (cc->clickeditem)->i2dt_affine() );
+ Geom::Affine i2d ( (this->clickeditem)->i2dt_affine() );
Geom::Affine d2i = i2d.inverse();
- SPPath *path = SP_PATH(cc->clickeditem);
+ SPPath *path = SP_PATH(this->clickeditem);
SPCurve *curve = path->get_curve();
- if (cc->clickedhandle == cc->endpt_handle[0]) {
- Geom::Point o = cc->endpt_handle[1]->pos;
+ if (this->clickedhandle == this->endpt_handle[0]) {
+ Geom::Point o = this->endpt_handle[1]->pos;
curve->stretch_endpoints(p * d2i, o * d2i);
}
else {
- Geom::Point o = cc->endpt_handle[0]->pos;
+ Geom::Point o = this->endpt_handle[0]->pos;
curve->stretch_endpoints(o * d2i, p * d2i);
}
sp_conn_reroute_path_immediate(path);
// Copy this to the temporary visible path
- cc->red_curve = path->get_curve_for_edit();
- cc->red_curve->transform(i2d);
+ this->red_curve = path->get_curve_for_edit();
+ this->red_curve->transform(i2d);
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), cc->red_curve);
- ret = TRUE;
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve);
+ ret = true;
break;
}
case SP_CONNECTOR_CONTEXT_STOP:
/* This is perfectly valid */
break;
default:
- if (!sp_event_context_knot_mouseover(cc)) {
- m.setup(dt);
+ if (!this->sp_event_context_knot_mouseover()) {
+ m.setup(desktop);
m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE));
m.unSetup();
}
@@ -708,24 +655,19 @@ connector_handle_motion_notify(ConnectorTool *const cc, GdkEventMotion const &me
return ret;
}
-static gint
-connector_handle_button_release(ConnectorTool *const cc, GdkEventButton const &revent)
-{
- gint ret = FALSE;
- ToolBase *event_context = SP_EVENT_CONTEXT(cc);
- if ( revent.button == 1 && !event_context->space_panning ) {
+bool ConnectorTool::_handleButtonRelease(GdkEventButton const &revent) {
+ bool ret = false;
- SPDesktop *desktop = cc->desktop;
+ if ( revent.button == 1 && !this->space_panning ) {
SPDocument *doc = sp_desktop_document(desktop);
-
SnapManager &m = desktop->namedview->snap_manager;
Geom::Point const event_w(revent.x, revent.y);
/* Find desktop coordinates */
- Geom::Point p = cc->desktop->w2d(event_w);
+ Geom::Point p = this->desktop->w2d(event_w);
- switch (cc->state) {
+ switch (this->state) {
//case SP_CONNECTOR_CONTEXT_POINT:
case SP_CONNECTOR_CONTEXT_DRAGGING:
{
@@ -733,21 +675,21 @@ connector_handle_button_release(ConnectorTool *const cc, GdkEventButton const &r
m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
m.unSetup();
- if (cc->within_tolerance)
+ if (this->within_tolerance)
{
- spcc_connector_finish_segment(cc, p);
- return TRUE;
+ this->_finishSegment(p);
+ return true;
}
// Connector has been created via a drag, end it now.
- spcc_connector_set_subsequent_point(cc, p);
- spcc_connector_finish_segment(cc, p);
+ this->_setSubsequentPoint(p);
+ this->_finishSegment(p);
// Test whether we clicked on a connection point
- conn_pt_handle_test(cc, p, &cc->ehref);
- if (cc->npoints != 0) {
- spcc_connector_finish(cc);
+ this->_ptHandleTest(p, &this->ehref);
+ if (this->npoints != 0) {
+ this->_finish();
}
- cc_set_active_conn(cc, cc->newconn);
- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
+ this->cc_set_active_conn(this->newconn);
+ this->state = SP_CONNECTOR_CONTEXT_IDLE;
break;
}
case SP_CONNECTOR_CONTEXT_REROUTING:
@@ -755,11 +697,11 @@ connector_handle_button_release(ConnectorTool *const cc, GdkEventButton const &r
m.setup(desktop);
m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
m.unSetup();
- cc_connector_rerouting_finish(cc, &p);
+ this->_reroutingFinish(&p);
doc->ensureUpToDate();
- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
- return TRUE;
+ this->state = SP_CONNECTOR_CONTEXT_IDLE;
+ return true;
break;
}
case SP_CONNECTOR_CONTEXT_STOP:
@@ -768,45 +710,41 @@ connector_handle_button_release(ConnectorTool *const cc, GdkEventButton const &r
default:
break;
}
- ret = TRUE;
+ ret = true;
}
return ret;
}
-static gint
-connector_handle_key_press(ConnectorTool *const cc, guint const keyval)
-{
- gint ret = FALSE;
+bool ConnectorTool::_handleKeyPress(guint const keyval) {
+ bool ret = false;
switch (keyval) {
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
- if (cc->npoints != 0) {
- spcc_connector_finish(cc);
- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
- ret = TRUE;
+ if (this->npoints != 0) {
+ this->_finish();
+ this->state = SP_CONNECTOR_CONTEXT_IDLE;
+ ret = true;
}
break;
case GDK_KEY_Escape:
- if (cc->state == SP_CONNECTOR_CONTEXT_REROUTING) {
-
- SPDesktop *desktop = cc->desktop;
+ if (this->state == SP_CONNECTOR_CONTEXT_REROUTING) {
SPDocument *doc = sp_desktop_document(desktop);
- cc_connector_rerouting_finish(cc, NULL);
+ this->_reroutingFinish(NULL);
DocumentUndo::undo(doc);
- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
+ this->state = SP_CONNECTOR_CONTEXT_IDLE;
desktop->messageStack()->flash( Inkscape::NORMAL_MESSAGE,
_("Connector endpoint drag cancelled."));
- ret = TRUE;
+ ret = true;
}
- else if (cc->npoints != 0) {
+ else if (this->npoints != 0) {
// if drawing, cancel, otherwise pass it up for deselecting
- cc->state = SP_CONNECTOR_CONTEXT_STOP;
- spcc_reset_colors(cc);
- ret = TRUE;
+ this->state = SP_CONNECTOR_CONTEXT_STOP;
+ this->_resetColors();
+ ret = true;
}
break;
default:
@@ -815,95 +753,82 @@ connector_handle_key_press(ConnectorTool *const cc, guint const keyval)
return ret;
}
-
-static void
-cc_connector_rerouting_finish(ConnectorTool *const cc, Geom::Point *const p)
-{
- SPDesktop *desktop = cc->desktop;
+void ConnectorTool::_reroutingFinish(Geom::Point *const p) {
SPDocument *doc = sp_desktop_document(desktop);
// Clear the temporary path:
- cc->red_curve->reset();
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), NULL);
+ this->red_curve->reset();
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), NULL);
if (p != NULL)
{
// Test whether we clicked on a connection point
gchar *shape_label;
- bool found = conn_pt_handle_test(cc, *p, &shape_label);
+ bool found = this->_ptHandleTest(*p, &shape_label);
if (found) {
- if (cc->clickedhandle == cc->endpt_handle[0]) {
- cc->clickeditem->setAttribute("inkscape:connection-start", shape_label, NULL);
+ if (this->clickedhandle == this->endpt_handle[0]) {
+ this->clickeditem->setAttribute("inkscape:connection-start", shape_label, NULL);
}
else {
- cc->clickeditem->setAttribute("inkscape:connection-end", shape_label, NULL);
+ this->clickeditem->setAttribute("inkscape:connection-end", shape_label, NULL);
}
g_free(shape_label);
}
}
- cc->clickeditem->setHidden(false);
- sp_conn_reroute_path_immediate(SP_PATH(cc->clickeditem));
- cc->clickeditem->updateRepr();
+ this->clickeditem->setHidden(false);
+ sp_conn_reroute_path_immediate(SP_PATH(this->clickeditem));
+ this->clickeditem->updateRepr();
DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR,
_("Reroute connector"));
- cc_set_active_conn(cc, cc->clickeditem);
+ this->cc_set_active_conn(this->clickeditem);
}
-static void
-spcc_reset_colors(ConnectorTool *cc)
-{
+void ConnectorTool::_resetColors() {
/* Red */
- cc->red_curve->reset();
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), NULL);
+ this->red_curve->reset();
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), NULL);
- cc->green_curve->reset();
- cc->npoints = 0;
+ this->green_curve->reset();
+ this->npoints = 0;
}
+void ConnectorTool::_setInitialPoint(Geom::Point const p) {
+ g_assert( this->npoints == 0 );
-static void
-spcc_connector_set_initial_point(ConnectorTool *const cc, Geom::Point const p)
-{
- g_assert( cc->npoints == 0 );
-
- cc->p[0] = p;
- cc->p[1] = p;
- cc->npoints = 2;
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), NULL);
+ this->p[0] = p;
+ this->p[1] = p;
+ this->npoints = 2;
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), NULL);
}
+void ConnectorTool::_setSubsequentPoint(Geom::Point const p) {
+ g_assert( this->npoints != 0 );
-static void
-spcc_connector_set_subsequent_point(ConnectorTool *const cc, Geom::Point const p)
-{
- g_assert( cc->npoints != 0 );
-
- SPDesktop *dt = cc->desktop;
- Geom::Point o = dt->dt2doc(cc->p[0]);
- Geom::Point d = dt->dt2doc(p);
+ Geom::Point o = desktop->dt2doc(this->p[0]);
+ Geom::Point d = desktop->dt2doc(p);
Avoid::Point src(o[Geom::X], o[Geom::Y]);
Avoid::Point dst(d[Geom::X], d[Geom::Y]);
- if (!cc->newConnRef) {
- Avoid::Router *router = sp_desktop_document(dt)->router;
- cc->newConnRef = new Avoid::ConnRef(router);
- cc->newConnRef->setEndpoint(Avoid::VertID::src, src);
- if (cc->isOrthogonal)
- cc->newConnRef->setRoutingType(Avoid::ConnType_Orthogonal);
+ if (!this->newConnRef) {
+ Avoid::Router *router = sp_desktop_document(desktop)->router;
+ this->newConnRef = new Avoid::ConnRef(router);
+ this->newConnRef->setEndpoint(Avoid::VertID::src, src);
+ if (this->isOrthogonal)
+ this->newConnRef->setRoutingType(Avoid::ConnType_Orthogonal);
else
- cc->newConnRef->setRoutingType(Avoid::ConnType_PolyLine);
+ this->newConnRef->setRoutingType(Avoid::ConnType_PolyLine);
}
// Set new endpoint.
- cc->newConnRef->setEndpoint(Avoid::VertID::tar, dst);
+ this->newConnRef->setEndpoint(Avoid::VertID::tar, dst);
// Immediately generate new routes for connector.
- cc->newConnRef->makePathInvalid();
- cc->newConnRef->router()->processTransaction();
+ this->newConnRef->makePathInvalid();
+ this->newConnRef->router()->processTransaction();
// Recreate curve from libavoid route.
- recreateCurve( cc->red_curve, cc->newConnRef, cc->curvature );
- cc->red_curve->transform(dt->doc2dt());
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), cc->red_curve);
+ recreateCurve( this->red_curve, this->newConnRef, this->curvature );
+ this->red_curve->transform(desktop->doc2dt());
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve);
}
@@ -912,21 +837,19 @@ spcc_connector_set_subsequent_point(ConnectorTool *const cc, Geom::Point const p
* If any anchors are defined, process these, optionally removing curves from white list
* Invoke _flush_white to write result back to object.
*/
-static void
-spcc_concat_colors_and_flush(ConnectorTool *cc)
-{
- SPCurve *c = cc->green_curve;
- cc->green_curve = new SPCurve();
+void ConnectorTool::_concatColorsAndFlush() {
+ SPCurve *c = this->green_curve;
+ this->green_curve = new SPCurve();
- cc->red_curve->reset();
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), NULL);
+ this->red_curve->reset();
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), NULL);
if (c->is_empty()) {
c->unref();
return;
}
- spcc_flush_white(cc, c);
+ this->_flushWhite(c);
c->unref();
}
@@ -940,9 +863,7 @@ spcc_concat_colors_and_flush(ConnectorTool *cc)
*
*/
-static void
-spcc_flush_white(ConnectorTool *cc, SPCurve *gc)
-{
+void ConnectorTool::_flushWhite(SPCurve *gc) {
SPCurve *c;
if (gc) {
@@ -953,9 +874,8 @@ spcc_flush_white(ConnectorTool *cc, SPCurve *gc)
}
/* Now we have to go back to item coordinates at last */
- c->transform(cc->desktop->dt2doc());
+ c->transform(this->desktop->dt2doc());
- SPDesktop *desktop = cc->desktop;
SPDocument *doc = sp_desktop_document(desktop);
Inkscape::XML::Document *xml_doc = doc->getReprDoc();
@@ -972,42 +892,42 @@ spcc_flush_white(ConnectorTool *cc, SPCurve *gc)
g_free(str);
/* Attach repr */
- cc->newconn = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr));
- cc->newconn->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ this->newconn = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr));
+ this->newconn->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
bool connection = false;
- cc->newconn->setAttribute( "inkscape:connector-type",
- cc->isOrthogonal ? "orthogonal" : "polyline", NULL );
- cc->newconn->setAttribute( "inkscape:connector-curvature",
- Glib::Ascii::dtostr(cc->curvature).c_str(), NULL );
- if (cc->shref)
+ this->newconn->setAttribute( "inkscape:connector-type",
+ this->isOrthogonal ? "orthogonal" : "polyline", NULL );
+ this->newconn->setAttribute( "inkscape:connector-curvature",
+ Glib::Ascii::dtostr(this->curvature).c_str(), NULL );
+ if (this->shref)
{
- cc->newconn->setAttribute( "inkscape:connection-start", cc->shref, NULL);
+ this->newconn->setAttribute( "inkscape:connection-start", this->shref, NULL);
connection = true;
}
- if (cc->ehref)
+ if (this->ehref)
{
- cc->newconn->setAttribute( "inkscape:connection-end", cc->ehref, NULL);
+ this->newconn->setAttribute( "inkscape:connection-end", this->ehref, NULL);
connection = true;
}
// Process pending updates.
- cc->newconn->updateRepr();
+ this->newconn->updateRepr();
doc->ensureUpToDate();
if (connection) {
// Adjust endpoints to shape edge.
- sp_conn_reroute_path_immediate(SP_PATH(cc->newconn));
- cc->newconn->updateRepr();
+ sp_conn_reroute_path_immediate(SP_PATH(this->newconn));
+ this->newconn->updateRepr();
}
- cc->newconn->doWriteTransform(cc->newconn->getRepr(), cc->newconn->transform, NULL, true);
+ this->newconn->doWriteTransform(this->newconn->getRepr(), this->newconn->transform, NULL, true);
// Only set the selection after we are finished with creating the attributes of
// the connector. Otherwise, the selection change may alter the defaults for
// values like curvature in the connector context, preventing subsequent lookup
// of their original values.
- cc->selection->set(repr);
+ this->selection->set(repr);
Inkscape::GC::release(repr);
}
@@ -1017,36 +937,30 @@ spcc_flush_white(ConnectorTool *cc, SPCurve *gc)
}
-static void
-spcc_connector_finish_segment(ConnectorTool *const cc, Geom::Point const /*p*/)
-{
- if (!cc->red_curve->is_empty()) {
- cc->green_curve->append_continuous(cc->red_curve, 0.0625);
+void ConnectorTool::_finishSegment(Geom::Point const /*p*/) {
+ if (!this->red_curve->is_empty()) {
+ this->green_curve->append_continuous(this->red_curve, 0.0625);
- cc->p[0] = cc->p[3];
- cc->p[1] = cc->p[4];
- cc->npoints = 2;
+ this->p[0] = this->p[3];
+ this->p[1] = this->p[4];
+ this->npoints = 2;
- cc->red_curve->reset();
+ this->red_curve->reset();
}
}
-
-static void
-spcc_connector_finish(ConnectorTool *const cc)
-{
- SPDesktop *const desktop = cc->desktop;
+void ConnectorTool::_finish() {
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing connector"));
- cc->red_curve->reset();
- spcc_concat_colors_and_flush(cc);
+ this->red_curve->reset();
+ this->_concatColorsAndFlush();
- cc->npoints = 0;
+ this->npoints = 0;
- if (cc->newConnRef) {
- cc->newConnRef->removeFromGraph();
- delete cc->newConnRef;
- cc->newConnRef = NULL;
+ if (this->newConnRef) {
+ this->newConnRef->removeFromGraph();
+ delete this->newConnRef;
+ this->newConnRef = NULL;
}
}
@@ -1056,7 +970,8 @@ cc_generic_knot_handler(SPCanvasItem *, GdkEvent *event, SPKnot *knot)
{
g_assert (knot != NULL);
- g_object_ref(knot);
+ //g_object_ref(knot);
+ knot_ref(knot);
ConnectorTool *cc = SP_CONNECTOR_CONTEXT(
knot->desktop->event_context);
@@ -1066,7 +981,7 @@ cc_generic_knot_handler(SPCanvasItem *, GdkEvent *event, SPKnot *knot)
gchar const *knot_tip = "Click to join at this point";
switch (event->type) {
case GDK_ENTER_NOTIFY:
- sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, TRUE);
+ knot->setFlag(SP_KNOT_MOUSEOVER, TRUE);
cc->active_handle = knot;
if (knot_tip)
@@ -1078,9 +993,14 @@ cc_generic_knot_handler(SPCanvasItem *, GdkEvent *event, SPKnot *knot)
consumed = TRUE;
break;
case GDK_LEAVE_NOTIFY:
- sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, FALSE);
+ knot->setFlag(SP_KNOT_MOUSEOVER, FALSE);
- cc->active_handle = NULL;
+ /* FIXME: the following test is a workaround for LP Bug #1273510.
+ * It seems that a signal is not correctly disconnected, maybe
+ * something missing in cc_clear_active_conn()? */
+ if (cc) {
+ cc->active_handle = NULL;
+ }
if (knot_tip) {
knot->desktop->event_context->defaultMessageContext()->clear();
@@ -1092,7 +1012,8 @@ cc_generic_knot_handler(SPCanvasItem *, GdkEvent *event, SPKnot *knot)
break;
}
- g_object_unref(knot);
+ //g_object_unref(knot);
+ knot_unref(knot);
return consumed;
}
@@ -1112,7 +1033,7 @@ endpt_handler(SPKnot */*knot*/, GdkEvent *event, ConnectorTool *cc)
if (cc->state == SP_CONNECTOR_CONTEXT_IDLE) {
cc->clickeditem = cc->active_conn;
cc->clickedhandle = cc->active_handle;
- cc_clear_active_conn(cc);
+ cc->cc_clear_active_conn();
cc->state = SP_CONNECTOR_CONTEXT_REROUTING;
// Disconnect from attached shape
@@ -1147,69 +1068,68 @@ endpt_handler(SPKnot */*knot*/, GdkEvent *event, ConnectorTool *cc)
return consumed;
}
-static void cc_active_shape_add_knot(ConnectorTool *cc, SPItem* item)
-{
- SPDesktop *desktop = cc->desktop;
- SPKnot *knot = sp_knot_new(desktop, 0);
+void ConnectorTool::_activeShapeAddKnot(SPItem* item) {
+ SPKnot *knot = new SPKnot(desktop, 0);
knot->owner = item;
knot->setShape(SP_KNOT_SHAPE_SQUARE);
knot->setSize(8);
knot->setAnchor(SP_ANCHOR_CENTER);
knot->setFill(0xffffff00, 0xff0000ff, 0xff0000ff);
- sp_knot_update_ctrl(knot);
+ knot->updateCtrl();
// We don't want to use the standard knot handler.
g_signal_handler_disconnect(G_OBJECT(knot->item),
knot->_event_handler_id);
+
knot->_event_handler_id = 0;
g_signal_connect(G_OBJECT(knot->item), "event",
G_CALLBACK(cc_generic_knot_handler), knot);
- sp_knot_set_position(knot, item->avoidRef->getConnectionPointPos() * desktop->doc2dt(), 0);
- sp_knot_show(knot);
- cc->knots[knot] = 1;
+
+ knot->setPosition(item->avoidRef->getConnectionPointPos() * desktop->doc2dt(), 0);
+ knot->show();
+ this->knots[knot] = 1;
}
-static void cc_set_active_shape(ConnectorTool *cc, SPItem *item)
-{
+void ConnectorTool::_setActiveShape(SPItem *item) {
g_assert(item != NULL );
- if (cc->active_shape != item)
+ if (this->active_shape != item)
{
// The active shape has changed
// Rebuild everything
- cc->active_shape = item;
+ this->active_shape = item;
// Remove existing active shape listeners
- if (cc->active_shape_repr) {
- sp_repr_remove_listener_by_data(cc->active_shape_repr, cc);
- Inkscape::GC::release(cc->active_shape_repr);
+ if (this->active_shape_repr) {
+ sp_repr_remove_listener_by_data(this->active_shape_repr, this);
+ Inkscape::GC::release(this->active_shape_repr);
- sp_repr_remove_listener_by_data(cc->active_shape_layer_repr, cc);
- Inkscape::GC::release(cc->active_shape_layer_repr);
+ sp_repr_remove_listener_by_data(this->active_shape_layer_repr, this);
+ Inkscape::GC::release(this->active_shape_layer_repr);
}
// Listen in case the active shape changes
- cc->active_shape_repr = item->getRepr();
- if (cc->active_shape_repr) {
- Inkscape::GC::anchor(cc->active_shape_repr);
- sp_repr_add_listener(cc->active_shape_repr, &shape_repr_events, cc);
-
- cc->active_shape_layer_repr = cc->active_shape_repr->parent();
- Inkscape::GC::anchor(cc->active_shape_layer_repr);
- sp_repr_add_listener(cc->active_shape_layer_repr, &layer_repr_events, cc);
+ this->active_shape_repr = item->getRepr();
+ if (this->active_shape_repr) {
+ Inkscape::GC::anchor(this->active_shape_repr);
+ sp_repr_add_listener(this->active_shape_repr, &shape_repr_events, this);
+
+ this->active_shape_layer_repr = this->active_shape_repr->parent();
+ Inkscape::GC::anchor(this->active_shape_layer_repr);
+ sp_repr_add_listener(this->active_shape_layer_repr, &layer_repr_events, this);
}
- cc_clear_active_knots(cc->knots);
+ cc_clear_active_knots(this->knots);
// The idea here is to try and add a group's children to solidify
// connection handling. We react to path objects with only one node.
for (SPObject *child = item->firstChild() ; child ; child = child->getNext() ) {
if (SP_IS_PATH(child) && SP_PATH(child)->nodesInPath() == 1) {
- cc_active_shape_add_knot(cc, (SPItem *) child);
+ this->_activeShapeAddKnot((SPItem *) child);
}
}
- cc_active_shape_add_knot(cc, item);
+ this->_activeShapeAddKnot(item);
}
else
@@ -1220,58 +1140,54 @@ static void cc_set_active_shape(ConnectorTool *cc, SPItem *item)
}
}
-
-static void
-cc_set_active_conn(ConnectorTool *cc, SPItem *item)
-{
+void ConnectorTool::cc_set_active_conn(SPItem *item) {
g_assert( SP_IS_PATH(item) );
const SPCurve *curve = SP_PATH(item)->get_curve_reference();
Geom::Affine i2dt = item->i2dt_affine();
- if (cc->active_conn == item)
+ if (this->active_conn == item)
{
if (curve->is_empty())
{
// Connector is invisible because it is clipped to the boundary of
// two overlpapping shapes.
- sp_knot_hide(cc->endpt_handle[0]);
- sp_knot_hide(cc->endpt_handle[1]);
+ this->endpt_handle[0]->hide();
+ this->endpt_handle[1]->hide();
}
else
{
// Just adjust handle positions.
Geom::Point startpt = *(curve->first_point()) * i2dt;
- sp_knot_set_position(cc->endpt_handle[0], startpt, 0);
+ this->endpt_handle[0]->setPosition(startpt, 0);
Geom::Point endpt = *(curve->last_point()) * i2dt;
- sp_knot_set_position(cc->endpt_handle[1], endpt, 0);
+ this->endpt_handle[1]->setPosition(endpt, 0);
}
return;
}
- cc->active_conn = item;
+ this->active_conn = item;
// Remove existing active conn listeners
- if (cc->active_conn_repr) {
- sp_repr_remove_listener_by_data(cc->active_conn_repr, cc);
- Inkscape::GC::release(cc->active_conn_repr);
- cc->active_conn_repr = NULL;
+ if (this->active_conn_repr) {
+ sp_repr_remove_listener_by_data(this->active_conn_repr, this);
+ Inkscape::GC::release(this->active_conn_repr);
+ this->active_conn_repr = NULL;
}
// Listen in case the active conn changes
- cc->active_conn_repr = item->getRepr();
- if (cc->active_conn_repr) {
- Inkscape::GC::anchor(cc->active_conn_repr);
- sp_repr_add_listener(cc->active_conn_repr, &shape_repr_events, cc);
+ this->active_conn_repr = item->getRepr();
+ if (this->active_conn_repr) {
+ Inkscape::GC::anchor(this->active_conn_repr);
+ sp_repr_add_listener(this->active_conn_repr, &shape_repr_events, this);
}
for (int i = 0; i < 2; ++i) {
-
// Create the handle if it doesn't exist
- if ( cc->endpt_handle[i] == NULL ) {
- SPKnot *knot = sp_knot_new(cc->desktop,
+ if ( this->endpt_handle[i] == NULL ) {
+ SPKnot *knot = new SPKnot(this->desktop,
_("<b>Connector endpoint</b>: drag to reroute or connect to new shapes"));
knot->setShape(SP_KNOT_SHAPE_SQUARE);
@@ -1279,34 +1195,36 @@ cc_set_active_conn(ConnectorTool *cc, SPItem *item)
knot->setAnchor(SP_ANCHOR_CENTER);
knot->setFill(0xffffff00, 0xff0000ff, 0xff0000ff);
knot->setStroke(0x000000ff, 0x000000ff, 0x000000ff);
- sp_knot_update_ctrl(knot);
+ knot->updateCtrl();
// We don't want to use the standard knot handler,
// since we don't want this knot to be draggable.
g_signal_handler_disconnect(G_OBJECT(knot->item),
knot->_event_handler_id);
+
knot->_event_handler_id = 0;
g_signal_connect(G_OBJECT(knot->item), "event",
G_CALLBACK(cc_generic_knot_handler), knot);
- cc->endpt_handle[i] = knot;
+ this->endpt_handle[i] = knot;
}
// Remove any existing handlers
- if (cc->endpt_handler_id[i]) {
+ if (this->endpt_handler_id[i]) {
g_signal_handlers_disconnect_by_func(
- G_OBJECT(cc->endpt_handle[i]->item),
- (void*)G_CALLBACK(endpt_handler), (gpointer) cc );
- cc->endpt_handler_id[i] = 0;
+ G_OBJECT(this->endpt_handle[i]->item),
+ (void*)G_CALLBACK(endpt_handler), (gpointer) this );
+
+ this->endpt_handler_id[i] = 0;
}
// Setup handlers for connector endpoints, this is
// is as 'after' so that cc_generic_knot_handler is
// triggered first for any endpoint.
- cc->endpt_handler_id[i] = g_signal_connect_after(
- G_OBJECT(cc->endpt_handle[i]->item), "event",
- G_CALLBACK(endpt_handler), cc);
+ this->endpt_handler_id[i] = g_signal_connect_after(
+ G_OBJECT(this->endpt_handle[i]->item), "event",
+ G_CALLBACK(endpt_handler), this);
}
if (curve->is_empty())
@@ -1317,13 +1235,13 @@ cc_set_active_conn(ConnectorTool *cc, SPItem *item)
}
Geom::Point startpt = *(curve->first_point()) * i2dt;
- sp_knot_set_position(cc->endpt_handle[0], startpt, 0);
+ this->endpt_handle[0]->setPosition(startpt, 0);
Geom::Point endpt = *(curve->last_point()) * i2dt;
- sp_knot_set_position(cc->endpt_handle[1], endpt, 0);
+ this->endpt_handle[1]->setPosition(endpt, 0);
- sp_knot_show(cc->endpt_handle[0]);
- sp_knot_show(cc->endpt_handle[1]);
+ this->endpt_handle[0]->show();
+ this->endpt_handle[1]->show();
}
void cc_create_connection_point(ConnectorTool* cc)
@@ -1334,15 +1252,18 @@ void cc_create_connection_point(ConnectorTool* cc)
{
cc_deselect_handle( cc->selected_handle );
}
- SPKnot *knot = sp_knot_new(cc->desktop, 0);
+
+ SPKnot *knot = new SPKnot(cc->desktop, 0);
+
// We do not process events on this knot.
g_signal_handler_disconnect(G_OBJECT(knot->item),
knot->_event_handler_id);
+
knot->_event_handler_id = 0;
cc_select_handle( knot );
cc->selected_handle = knot;
- sp_knot_show(cc->selected_handle);
+ cc->selected_handle->show();
cc->state = SP_CONNECTOR_CONTEXT_NEWCONNPOINT;
}
}
@@ -1422,7 +1343,7 @@ void cc_selection_set_avoid(bool const set_avoid)
DocumentUndo::done(document, SP_VERB_CONTEXT_CONNECTOR, event_desc);
}
-void ConnectorTool::selection_changed(Inkscape::Selection *selection) {
+void ConnectorTool::_selectionChanged(Inkscape::Selection *selection) {
SPItem *item = selection->singleItem();
if (this->active_conn == item) {
@@ -1431,12 +1352,12 @@ void ConnectorTool::selection_changed(Inkscape::Selection *selection) {
}
if (item == NULL) {
- cc_clear_active_conn(this);
+ this->cc_clear_active_conn();
return;
}
if (cc_item_is_connector(item)) {
- cc_set_active_conn(this, item);
+ this->cc_set_active_conn(item);
}
}
@@ -1449,7 +1370,7 @@ shape_event_attr_deleted(Inkscape::XML::Node */*repr*/, Inkscape::XML::Node *chi
if (child == cc->active_shape_repr) {
// The active shape has been deleted. Clear active shape.
- cc_clear_active_shape(cc);
+ cc->cc_clear_active_shape();
}
}
@@ -1469,12 +1390,12 @@ shape_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
{
if (repr == cc->active_shape_repr) {
// Active shape has moved. Clear active shape.
- cc_clear_active_shape(cc);
+ cc->cc_clear_active_shape();
}
else if (repr == cc->active_conn_repr) {
// The active conn has been moved.
// Set it again, which just sets new handle positions.
- cc_set_active_conn(cc, cc->active_conn);
+ cc->cc_set_active_conn(cc->active_conn);
}
}
}
diff --git a/src/ui/tools/connector-tool.h b/src/ui/tools/connector-tool.h
index 7cd6a6dad..868b8e77c 100644
--- a/src/ui/tools/connector-tool.h
+++ b/src/ui/tools/connector-tool.h
@@ -12,25 +12,34 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#include <stddef.h>
-#include <sigc++/sigc++.h>
-#include <sigc++/connection.h>
-#include "ui/tools/tool-base.h"
+#include <map>
+#include <string>
+
#include <2geom/point.h>
-#include "libavoid/connector.h"
-#include <glibmm/i18n.h>
+#include <sigc++/connection.h>
-#define SP_CONNECTOR_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::ConnectorTool*>((Inkscape::UI::Tools::ToolBase*)obj))
-//#define SP_IS_CONNECTOR_CONTEXT(obj) (dynamic_cast<const ConnectorTool*>((const ToolBase*)obj) != NULL)
+#include "ui/tools/tool-base.h"
-struct SPKnot;
+class SPItem;
class SPCurve;
+class SPKnot;
+struct SPCanvasItem;
-namespace Inkscape
-{
- class Selection;
+namespace Avoid {
+ class ConnRef;
}
+namespace Inkscape {
+ class Selection;
+
+ namespace XML {
+ class Node;
+ }
+}
+
+#define SP_CONNECTOR_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::ConnectorTool*>((Inkscape::UI::Tools::ToolBase*)obj))
+//#define SP_IS_CONNECTOR_CONTEXT(obj) (dynamic_cast<const ConnectorTool*>((const ToolBase*)obj) != NULL)
+
enum {
SP_CONNECTOR_CONTEXT_IDLE,
SP_CONNECTOR_CONTEXT_DRAGGING,
@@ -108,8 +117,31 @@ public:
virtual const std::string& getPrefsPath();
+ void cc_clear_active_shape();
+ void cc_set_active_conn(SPItem *item);
+ void cc_clear_active_conn();
+
private:
- void selection_changed(Inkscape::Selection *selection);
+ void _selectionChanged(Inkscape::Selection *selection);
+
+ bool _handleButtonPress(GdkEventButton const &bevent);
+ bool _handleMotionNotify(GdkEventMotion const &mevent);
+ bool _handleButtonRelease(GdkEventButton const &revent);
+ bool _handleKeyPress(guint const keyval);
+
+ void _setInitialPoint(Geom::Point const p);
+ void _setSubsequentPoint(Geom::Point const p);
+ void _finishSegment(Geom::Point p);
+ void _resetColors();
+ void _finish();
+ void _concatColorsAndFlush();
+ void _flushWhite(SPCurve *gc);
+
+ void _activeShapeAddKnot(SPItem* item);
+ void _setActiveShape(SPItem *item);
+ bool _ptHandleTest(Geom::Point& p, gchar **href);
+
+ void _reroutingFinish(Geom::Point *const p);
};
void cc_selection_set_avoid(bool const set_ignore);
diff --git a/src/ui/tools/dropper-tool.cpp b/src/ui/tools/dropper-tool.cpp
index 9c47b50e9..99d42a211 100644
--- a/src/ui/tools/dropper-tool.cpp
+++ b/src/ui/tools/dropper-tool.cpp
@@ -72,21 +72,17 @@ const std::string& DropperTool::getPrefsPath() {
const std::string DropperTool::prefsPath = "/tools/dropper";
-DropperTool::DropperTool() : ToolBase() {
- this->R = 0;
- this->G = 0;
- this->B = 0;
- this->alpha = 0;
- this->dragging = false;
-
- this->grabbed = 0;
- this->area = 0;
- this->centre = Geom::Point(0, 0);
-
- this->cursor_shape = cursor_dropper_f_xpm;
- this->hot_x = 7;
- this->hot_y = 7;
-
+DropperTool::DropperTool()
+ : ToolBase(cursor_dropper_f_xpm, 7, 7)
+ , R(0)
+ , G(0)
+ , B(0)
+ , alpha(0)
+ , dragging(false)
+ , grabbed(NULL)
+ , area(NULL)
+ , centre(0, 0)
+{
cursor_dropper_fill = sp_cursor_new_from_xpm(cursor_dropper_f_xpm , 7, 7);
cursor_dropper_stroke = sp_cursor_new_from_xpm(cursor_dropper_s_xpm , 7, 7);
}
@@ -152,6 +148,8 @@ void DropperTool::finish() {
#endif
cursor_dropper_fill = NULL;
}
+
+ ToolBase::finish();
}
/**
@@ -338,6 +336,10 @@ bool DropperTool::root_handler(GdkEvent* event) {
if (prefs->getBool("/tools/dropper/onetimepick", false)) {
prefs->setBool("/tools/dropper/onetimepick", false);
sp_toggle_dropper(desktop);
+
+ // sp_toggle_dropper will delete ourselves.
+ // Thus, make sure we return immediately.
+ return true;
}
ret = TRUE;
diff --git a/src/ui/tools/dropper-tool.h b/src/ui/tools/dropper-tool.h
index dd6f25bb6..cfeb91dab 100644
--- a/src/ui/tools/dropper-tool.h
+++ b/src/ui/tools/dropper-tool.h
@@ -12,8 +12,12 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#include <2geom/point.h>
+
#include "ui/tools/tool-base.h"
+struct SPCanvasItem;
+
#define SP_DROPPER_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::DropperTool*>((Inkscape::UI::Tools::ToolBase*)obj))
#define SP_IS_DROPPER_CONTEXT(obj) (dynamic_cast<const Inkscape::UI::Tools::DropperTool*>((const Inkscape::UI::Tools::ToolBase*)obj) != NULL)
diff --git a/src/ui/tools/dynamic-base.cpp b/src/ui/tools/dynamic-base.cpp
index cec58dce9..eb789d850 100644
--- a/src/ui/tools/dynamic-base.cpp
+++ b/src/ui/tools/dynamic-base.cpp
@@ -10,6 +10,7 @@
#include "preferences.h"
#include "display/sp-canvas-item.h"
#include "desktop.h"
+#include "display/curve.h"
#define MIN_PRESSURE 0.0
#define MAX_PRESSURE 1.0
@@ -23,40 +24,41 @@ namespace Inkscape {
namespace UI {
namespace Tools {
-DynamicBase::DynamicBase() :
- ToolBase(),
- accumulated(NULL),
- segments(NULL),
- currentshape(NULL),
- currentcurve(NULL),
- cal1(NULL),
- cal2(NULL),
- point1(),
- point2(),
- repr(NULL),
- cur(0,0),
- vel(0,0),
- vel_max(0),
- acc(0,0),
- ang(0,0),
- last(0,0),
- del(0,0),
- pressure(DEFAULT_PRESSURE),
- xtilt(0),
- ytilt(0),
- dragging(FALSE),
- usepressure(FALSE),
- usetilt(FALSE),
- mass(0.3),
- drag(DRAG_DEFAULT),
- angle(30.0),
- width(0.2),
- vel_thin(0.1),
- flatness(0.9),
- tremor(0),
- cap_rounding(0),
- is_drawing(false),
- abs_width(false)
+DynamicBase::DynamicBase(gchar const *const *cursor_shape, gint hot_x, gint hot_y)
+ : ToolBase(cursor_shape, hot_x, hot_y)
+ , accumulated(NULL)
+ , segments(NULL)
+ , currentshape(NULL)
+ , currentcurve(NULL)
+ , cal1(NULL)
+ , cal2(NULL)
+ , point1()
+ , point2()
+ , npoints(0)
+ , repr(NULL)
+ , cur(0, 0)
+ , vel(0, 0)
+ , vel_max(0)
+ , acc(0, 0)
+ , ang(0, 0)
+ , last(0, 0)
+ , del(0, 0)
+ , pressure(DEFAULT_PRESSURE)
+ , xtilt(0)
+ , ytilt(0)
+ , dragging(false)
+ , usepressure(false)
+ , usetilt(false)
+ , mass(0.3)
+ , drag(DRAG_DEFAULT)
+ , angle(30.0)
+ , width(0.2)
+ , vel_thin(0.1)
+ , flatness(0.9)
+ , tremor(0)
+ , cap_rounding(0)
+ , is_drawing(false)
+ , abs_width(false)
{
}
diff --git a/src/ui/tools/dynamic-base.h b/src/ui/tools/dynamic-base.h
index 9218eabd3..c948fa286 100644
--- a/src/ui/tools/dynamic-base.h
+++ b/src/ui/tools/dynamic-base.h
@@ -20,8 +20,15 @@
*/
#include "ui/tools/tool-base.h"
-#include "display/curve.h"
-#include <2geom/point.h>
+
+struct SPCanvasItem;
+class SPCurve;
+
+namespace Inkscape {
+ namespace XML {
+ class Node;
+ }
+}
#define SAMPLING_SIZE 8 /* fixme: ?? */
@@ -31,7 +38,7 @@ namespace Tools {
class DynamicBase : public ToolBase {
public:
- DynamicBase();
+ DynamicBase(gchar const *const *cursor_shape, gint hot_x, gint hot_y);
virtual ~DynamicBase();
virtual void set(const Inkscape::Preferences::Entry& val);
@@ -81,9 +88,9 @@ protected:
gdouble ytilt;
/* attributes */
- guint dragging : 1; /* mouse state: mouse is dragging */
- guint usepressure : 1;
- guint usetilt : 1;
+ bool dragging; /* mouse state: mouse is dragging */
+ bool usepressure;
+ bool usetilt;
double mass, drag;
double angle;
double width;
diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp
index 270987d27..4106785e7 100644
--- a/src/ui/tools/eraser-tool.cpp
+++ b/src/ui/tools/eraser-tool.cpp
@@ -66,6 +66,7 @@
#include "verbs.h"
#include <2geom/math-utils.h>
#include <2geom/pathvector.h>
+#include "display/curve.h"
#include "ui/tools/eraser-tool.h"
@@ -103,10 +104,9 @@ const std::string& EraserTool::getPrefsPath() {
const std::string EraserTool::prefsPath = "/tools/eraser";
-EraserTool::EraserTool() : DynamicBase() {
- this->cursor_shape = cursor_eraser_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
+EraserTool::EraserTool()
+ : DynamicBase(cursor_eraser_xpm, 4, 4)
+{
}
EraserTool::~EraserTool() {
diff --git a/src/ui/tools/eraser-tool.h b/src/ui/tools/eraser-tool.h
index eb7eb16e8..110f57ba3 100644
--- a/src/ui/tools/eraser-tool.h
+++ b/src/ui/tools/eraser-tool.h
@@ -19,6 +19,8 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#include <2geom/point.h>
+
#include "ui/tools/dynamic-base.h"
#define ERC_MIN_PRESSURE 0.0
diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp
index 0b72bc9f2..d74848dc6 100644
--- a/src/ui/tools/flood-tool.cpp
+++ b/src/ui/tools/flood-tool.cpp
@@ -94,17 +94,12 @@ const std::string& FloodTool::getPrefsPath() {
const std::string FloodTool::prefsPath = "/tools/paintbucket";
-FloodTool::FloodTool() : ToolBase() {
- this->cursor_shape = cursor_paintbucket_xpm;
- this->hot_x = 11;
- this->hot_y = 30;
- this->xp = 0;
- this->yp = 0;
+FloodTool::FloodTool()
+ : ToolBase(cursor_paintbucket_xpm, 11, 30)
+ , item(NULL)
+{
+ // TODO: Why does the flood tool use a hardcoded tolerance instead of a pref?
this->tolerance = 4;
- this->within_tolerance = false;
- this->item_to_select = NULL;
-
- this->item = NULL;
}
FloodTool::~FloodTool() {
@@ -794,7 +789,7 @@ static void sp_flood_do_flood_fill(ToolBase *event_context, GdkEvent *event, boo
cairo_surface_t *s = cairo_image_surface_create_for_data(
px, CAIRO_FORMAT_ARGB32, width, height, stride);
- Inkscape::DrawingContext ct(s, Geom::Point(0,0));
+ Inkscape::DrawingContext dc(s, Geom::Point(0,0));
// cairo_translate not necessary here - surface origin is at 0,0
SPNamedView *nv = sp_desktop_namedview(desktop);
@@ -802,12 +797,12 @@ static void sp_flood_do_flood_fill(ToolBase *event_context, GdkEvent *event, boo
// bgcolor is 0xrrggbbaa, we need 0xaarrggbb
dtc = (bgcolor >> 8) | (bgcolor << 24);
- ct.setSource(bgcolor);
- ct.setOperator(CAIRO_OPERATOR_SOURCE);
- ct.paint();
- ct.setOperator(CAIRO_OPERATOR_OVER);
+ dc.setSource(bgcolor);
+ dc.setOperator(CAIRO_OPERATOR_SOURCE);
+ dc.paint();
+ dc.setOperator(CAIRO_OPERATOR_OVER);
- drawing.render(ct, final_bbox);
+ drawing.render(dc, final_bbox);
//cairo_surface_write_to_png( s, "cairo.png" );
diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp
index b80a3a503..df2e6f517 100644
--- a/src/ui/tools/freehand-base.cpp
+++ b/src/ui/tools/freehand-base.cpp
@@ -72,37 +72,31 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc);
static void spdc_reset_white(FreehandBase *dc);
static void spdc_free_colors(FreehandBase *dc);
-FreehandBase::FreehandBase() : ToolBase() {
- this->selection = 0;
- this->grab = 0;
- this->anchor_statusbar = false;
-
- this->attach = FALSE;
-
- this->red_color = 0xff00007f;
- this->blue_color = 0x0000ff7f;
- this->green_color = 0x00ff007f;
- this->red_curve_is_valid = false;
-
- this->red_bpath = NULL;
- this->red_curve = NULL;
-
- this->blue_bpath = NULL;
- this->blue_curve = NULL;
-
- this->green_bpaths = NULL;
- this->green_curve = NULL;
- this->green_anchor = NULL;
- this->green_closed = false;
-
- this->white_item = NULL;
- this->white_curves = NULL;
- this->white_anchors = NULL;
-
- this->sa = NULL;
- this->ea = NULL;
-
- this->waiting_LPE_type = Inkscape::LivePathEffect::INVALID_LPE;
+FreehandBase::FreehandBase(gchar const *const *cursor_shape, gint hot_x, gint hot_y)
+ : ToolBase(cursor_shape, hot_x, hot_y)
+ , selection(NULL)
+ , grab(NULL)
+ , attach(false)
+ , red_color(0xff00007f)
+ , blue_color(0x0000ff7f)
+ , green_color(0x00ff007f)
+ , red_bpath(NULL)
+ , red_curve(NULL)
+ , blue_bpath(NULL)
+ , blue_curve(NULL)
+ , green_bpaths(NULL)
+ , green_curve(NULL)
+ , green_anchor(NULL)
+ , green_closed(false)
+ , white_item(NULL)
+ , white_curves(NULL)
+ , white_anchors(NULL)
+ , sa(NULL)
+ , ea(NULL)
+ , waiting_LPE_type(Inkscape::LivePathEffect::INVALID_LPE)
+ , red_curve_is_valid(false)
+ , anchor_statusbar(false)
+{
}
FreehandBase::~FreehandBase() {
@@ -169,6 +163,8 @@ void FreehandBase::finish() {
}
spdc_free_colors(this);
+
+ ToolBase::finish();
}
void FreehandBase::set(const Inkscape::Preferences::Entry& /*value*/) {
@@ -470,7 +466,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item,
}
}
if (SP_IS_PEN_CONTEXT(dc)) {
- sp_pen_context_set_polyline_mode(SP_PEN_CONTEXT(dc));
+ SP_PEN_CONTEXT(dc)->setPolylineMode();
}
}
}
diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h
index 7e53684e3..5a4b91800 100644
--- a/src/ui/tools/freehand-base.h
+++ b/src/ui/tools/freehand-base.h
@@ -14,22 +14,29 @@
* Released under GNU GPL
*/
-#include <stddef.h>
-#include <sigc++/sigc++.h>
-#include <2geom/point.h>
+#include <sigc++/connection.h>
+
#include "ui/tools/tool-base.h"
-#include "live_effects/effect.h"
+#include "live_effects/effect-enum.h"
+
+struct SPCanvasItem;
+class SPCurve;
+struct SPDrawAnchor;
+
+namespace Inkscape {
+ class Selection;
+}
+
+namespace boost {
+ template<class T>
+ class optional;
+}
/* Freehand context */
#define SP_DRAW_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::FreehandBase*>((Inkscape::UI::Tools::ToolBase*)obj))
#define SP_IS_DRAW_CONTEXT(obj) (dynamic_cast<const Inkscape::UI::Tools::FreehandBase*>((const Inkscape::UI::Tools::ToolBase*)obj) != NULL)
-struct SPDrawAnchor;
-namespace Inkscape
-{
- class Selection;
-}
namespace Inkscape {
namespace UI {
@@ -37,13 +44,13 @@ namespace Tools {
class FreehandBase : public ToolBase {
public:
- FreehandBase();
+ FreehandBase(gchar const *const *cursor_shape, gint hot_x, gint hot_y);
virtual ~FreehandBase();
Inkscape::Selection *selection;
SPCanvasItem *grab;
- guint attach : 1;
+ bool attach;
guint32 red_color;
guint32 blue_color;
diff --git a/src/ui/tools/gradient-tool.cpp b/src/ui/tools/gradient-tool.cpp
index e4ab7b424..a0bbfbaf1 100644
--- a/src/ui/tools/gradient-tool.cpp
+++ b/src/ui/tools/gradient-tool.cpp
@@ -74,20 +74,16 @@ const std::string& GradientTool::getPrefsPath() {
const std::string GradientTool::prefsPath = "/tools/gradient";
-GradientTool::GradientTool() : ToolBase() {
- this->node_added = false;
- this->subselcon = 0;
- this->selcon = 0;
-
- this->cursor_addnode = false;
- this->cursor_shape = cursor_gradient_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
- this->xp = 0;
- this->yp = 0;
+GradientTool::GradientTool()
+ : ToolBase(cursor_gradient_xpm, 4, 4)
+ , cursor_addnode(false)
+ , node_added(false)
+// TODO: Why are these connections stored as pointers?
+ , selcon(NULL)
+ , subselcon(NULL)
+{
+ // TODO: This value is overwritten in the root handler
this->tolerance = 6;
- this->within_tolerance = false;
- this->item_to_select = NULL;
}
GradientTool::~GradientTool() {
@@ -339,10 +335,12 @@ sp_gradient_context_add_stops_between_selected_stops (GradientTool *rc)
SPGradient *gradient = getGradient(d->item, d->fill_or_stroke);
SPGradient *vector = sp_gradient_get_forked_vector_if_necessary (gradient, false);
SPStop *this_stop = sp_get_stop_i (vector, d->point_i);
- SPStop *next_stop = this_stop->getNextStop();
- if (this_stop && next_stop) {
- these_stops = g_slist_prepend (these_stops, this_stop);
- next_stops = g_slist_prepend (next_stops, next_stop);
+ if (this_stop) {
+ SPStop *next_stop = this_stop->getNextStop();
+ if (next_stop) {
+ these_stops = g_slist_prepend (these_stops, this_stop);
+ next_stops = g_slist_prepend (next_stops, next_stop);
+ }
}
}
}
diff --git a/src/ui/tools/lpe-tool.cpp b/src/ui/tools/lpe-tool.cpp
index a5406f1c5..9ab6d7814 100644
--- a/src/ui/tools/lpe-tool.cpp
+++ b/src/ui/tools/lpe-tool.cpp
@@ -81,16 +81,14 @@ const std::string& LpeTool::getPrefsPath() {
const std::string LpeTool::prefsPath = "/tools/lpetool";
-LpeTool::LpeTool() : PenTool() {
- this->mode = Inkscape::LivePathEffect::BEND_PATH;
- this->shape_editor = 0;
-
- this->cursor_shape = cursor_crosshairs_xpm;
- this->hot_x = 7;
- this->hot_y = 7;
-
- this->canvas_bbox = NULL;
- this->measuring_items = new std::map<SPPath *, SPCanvasItem*>;
+LpeTool::LpeTool()
+ : PenTool(cursor_crosshairs_xpm, 7, 7)
+ , shape_editor(NULL)
+ , canvas_bbox(NULL)
+ , mode(Inkscape::LivePathEffect::BEND_PATH)
+// TODO: pointer?
+ , measuring_items(new std::map<SPPath *, SPCanvasItem*>)
+{
}
LpeTool::~LpeTool() {
@@ -193,7 +191,7 @@ bool LpeTool::root_handler(GdkEvent* event) {
bool ret = false;
- if (sp_pen_context_has_waiting_LPE(this)) {
+ if (this->hasWaitingLPE()) {
// quit when we are waiting for a LPE to be applied
//ret = ((ToolBaseClass *) sp_lpetool_context_parent_class)->root_handler(event_context, event);
return PenTool::root_handler(event);
@@ -224,7 +222,7 @@ bool LpeTool::root_handler(GdkEvent* event) {
//bool over_stroke = lc->shape_editor->is_over_stroke(Geom::Point(event->button.x, event->button.y), true);
- sp_pen_context_wait_for_LPE_mouse_clicks(this, type, Inkscape::LivePathEffect::Effect::acceptsNumClicks(type));
+ this->waitForLPEMouseClicks(type, Inkscape::LivePathEffect::Effect::acceptsNumClicks(type));
// we pass the mouse click on to pen tool as the first click which it should collect
//ret = ((ToolBaseClass *) sp_lpetool_context_parent_class)->root_handler(event_context, event);
diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp
index 0d823dfda..2c85874bc 100644
--- a/src/ui/tools/measure-tool.cpp
+++ b/src/ui/tools/measure-tool.cpp
@@ -43,6 +43,7 @@
#include "sp-namedview.h"
#include "enums.h"
#include "ui/control-manager.h"
+#include "knot-enums.h"
using Inkscape::ControlManager;
using Inkscape::CTLINE_SECONDARY;
@@ -236,12 +237,10 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const &center, Geom
} // namespace
-MeasureTool::MeasureTool() : ToolBase() {
- this->grabbed = 0;
-
- this->cursor_shape = cursor_measure_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
+MeasureTool::MeasureTool()
+ : ToolBase(cursor_measure_xpm, 4, 4)
+ , grabbed(NULL)
+{
}
MeasureTool::~MeasureTool() {
@@ -254,6 +253,8 @@ void MeasureTool::finish() {
sp_canvas_item_ungrab(this->grabbed, GDK_CURRENT_TIME);
this->grabbed = NULL;
}
+
+ ToolBase::finish();
}
//void MeasureTool::setup() {
diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp
index 4e7617f44..7d6d3bc23 100644
--- a/src/ui/tools/mesh-tool.cpp
+++ b/src/ui/tools/mesh-tool.cpp
@@ -75,20 +75,18 @@ const std::string& MeshTool::getPrefsPath() {
const std::string MeshTool::prefsPath = "/tools/mesh";
-MeshTool::MeshTool() : ToolBase() {
- this->selcon = 0;
- this->node_added = false;
- this->subselcon = 0;
-
- this->cursor_addnode = false;
- this->cursor_shape = cursor_gradient_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
- this->xp = 0;
- this->yp = 0;
+// TODO: The gradient tool class looks like a 1:1 copy.
+
+MeshTool::MeshTool()
+ : ToolBase(cursor_gradient_xpm, 4, 4)
+ , cursor_addnode(false)
+ , node_added(false)
+// TODO: Why are these connections stored as pointers?
+ , selcon(NULL)
+ , subselcon(NULL)
+{
+ // TODO: This value is overwritten in the root handler
this->tolerance = 6;
- this->within_tolerance = false;
- this->item_to_select = NULL;
}
MeshTool::~MeshTool() {
diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp
index 7e33b1a4c..b1e11bd66 100644
--- a/src/ui/tools/node-tool.cpp
+++ b/src/ui/tools/node-tool.cpp
@@ -126,30 +126,27 @@ const std::string NodeTool::prefsPath = "/tools/nodes";
SPCanvasGroup *create_control_group(SPDesktop *d);
-NodeTool::NodeTool() : ToolBase() {
- this->show_handles = false;
- this->single_node_transform_handles = false;
- this->show_transform_handles = false;
- this->cursor_drag = false;
- this->live_objects = false;
- this->edit_clipping_paths = false;
- this->live_outline = false;
- this->flashed_item = 0;
- this->_transform_handle_group = 0;
- this->show_path_direction = false;
- this->_last_over = 0;
- this->edit_masks = false;
- this->show_outline = false;
- this->flash_tempitem = 0;
-
- this->cursor_shape = cursor_node_xpm;
- this->hot_x = 1;
- this->hot_y = 1;
-
- this->_selected_nodes = 0;
- this->_multipath = 0;
- this->_selector = 0;
- this->_path_data = 0;
+NodeTool::NodeTool()
+ : ToolBase(cursor_node_xpm, 1, 1)
+ , _selected_nodes(NULL)
+ , _multipath(NULL)
+ , edit_clipping_paths(false)
+ , edit_masks(false)
+ , flashed_item(NULL)
+ , flash_tempitem(NULL)
+ , _selector(NULL)
+ , _path_data(NULL)
+ , _transform_handle_group(NULL)
+ , _last_over(NULL)
+ , cursor_drag(false)
+ , show_handles(false)
+ , show_outline(false)
+ , live_outline(false)
+ , live_objects(false)
+ , show_path_direction(false)
+ , show_transform_handles(false)
+ , single_node_transform_handles(false)
+{
}
SPCanvasGroup *create_control_group(SPDesktop *d)
diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp
index dc5e801c0..09c0a2a4f 100644
--- a/src/ui/tools/pen-tool.cpp
+++ b/src/ui/tools/pen-tool.cpp
@@ -50,29 +50,8 @@ namespace Inkscape {
namespace UI {
namespace Tools {
-static void spdc_pen_set_initial_point(PenTool *pc, Geom::Point const p);
-static void spdc_pen_set_subsequent_point(PenTool *const pc, Geom::Point const p, bool statusbar, guint status = 0);
-static void spdc_pen_set_ctrl(PenTool *pc, Geom::Point const p, guint state);
-static void spdc_pen_finish_segment(PenTool *pc, Geom::Point p, guint state);
-
-static void spdc_pen_finish(PenTool *pc, gboolean closed);
-
-static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bevent);
-static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &mevent);
-static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &revent);
-static gint pen_handle_2button_press(PenTool *const pc, GdkEventButton const &bevent);
-static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event);
-static void spdc_reset_colors(PenTool *pc);
-
-static void pen_disable_events(PenTool *const pc);
-static void pen_enable_events(PenTool *const pc);
-
static Geom::Point pen_drag_origin_w(0, 0);
static bool pen_within_tolerance = false;
-
-static int pen_next_paraxial_direction(const PenTool *const pc, Geom::Point const &pt, Geom::Point const &origin, guint state);
-static void pen_set_to_nearest_horiz_vert(const PenTool *const pc, Geom::Point &pt, guint const state, bool snap);
-
static int pen_last_paraxial_dir = 0; // last used direction in horizontal/vertical mode; 0 = horizontal, 1 = vertical
namespace {
@@ -89,29 +68,44 @@ const std::string& PenTool::getPrefsPath() {
const std::string PenTool::prefsPath = "/tools/freehand/pen";
-PenTool::PenTool() : FreehandBase() {
- this->polylines_only = false;
- this->polylines_paraxial = false;
- this->expecting_clicks_for_LPE = 0;
-
- this->cursor_shape = cursor_pen_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
-
- this->npoints = 0;
- this->mode = MODE_CLICK;
- this->state = POINT;
-
- this->c0 = NULL;
- this->c1 = NULL;
- this->cl0 = NULL;
- this->cl1 = NULL;
-
- this->events_disabled = 0;
+PenTool::PenTool()
+ : FreehandBase(cursor_pen_xpm, 4, 4)
+ , p()
+ , npoints(0)
+ , mode(MODE_CLICK)
+ , state(POINT)
+ , polylines_only(false)
+ , polylines_paraxial(false)
+ , num_clicks(0)
+ , expecting_clicks_for_LPE(0)
+ , waiting_LPE(NULL)
+ , waiting_item(NULL)
+ , c0(NULL)
+ , c1(NULL)
+ , cl0(NULL)
+ , cl1(NULL)
+ , events_disabled(false)
+{
+}
- this->num_clicks = 0;
- this->waiting_LPE = NULL;
- this->waiting_item = NULL;
+PenTool::PenTool(gchar const *const *cursor_shape, gint hot_x, gint hot_y)
+ : FreehandBase(cursor_shape, hot_x, hot_y)
+ , p()
+ , npoints(0)
+ , mode(MODE_CLICK)
+ , state(POINT)
+ , polylines_only(false)
+ , polylines_paraxial(false)
+ , num_clicks(0)
+ , expecting_clicks_for_LPE(0)
+ , waiting_LPE(NULL)
+ , waiting_item(NULL)
+ , c0(NULL)
+ , c1(NULL)
+ , cl0(NULL)
+ , cl1(NULL)
+ , events_disabled(false)
+{
}
PenTool::~PenTool() {
@@ -138,11 +132,11 @@ PenTool::~PenTool() {
}
}
-void sp_pen_context_set_polyline_mode(PenTool *const pc) {
+void PenTool::setPolylineMode() {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0);
- pc->polylines_only = (mode == 2 || mode == 3);
- pc->polylines_paraxial = (mode == 3);
+ this->polylines_only = (mode == 2 || mode == 3);
+ this->polylines_paraxial = (mode == 3);
}
/**
@@ -172,7 +166,7 @@ void PenTool::setup() {
this->anchor_statusbar = false;
- sp_pen_context_set_polyline_mode(this);
+ this->setPolylineMode();
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (prefs->getBool("/tools/freehand/pen/selcue")) {
@@ -180,19 +174,18 @@ void PenTool::setup() {
}
}
-static void pen_cancel (PenTool *const pc)
-{
- pc->num_clicks = 0;
- pc->state = PenTool::STOP;
- spdc_reset_colors(pc);
- sp_canvas_item_hide(pc->c0);
- sp_canvas_item_hide(pc->c1);
- sp_canvas_item_hide(pc->cl0);
- sp_canvas_item_hide(pc->cl1);
- pc->message_context->clear();
- pc->message_context->flash(Inkscape::NORMAL_MESSAGE, _("Drawing cancelled"));
-
- pc->desktop->canvas->endForcedFullRedraws();
+void PenTool::_cancel() {
+ this->num_clicks = 0;
+ this->state = PenTool::STOP;
+ this->_resetColors();
+ sp_canvas_item_hide(this->c0);
+ sp_canvas_item_hide(this->c1);
+ sp_canvas_item_hide(this->cl0);
+ sp_canvas_item_hide(this->cl1);
+ this->message_context->clear();
+ this->message_context->flash(Inkscape::NORMAL_MESSAGE, _("Drawing cancelled"));
+
+ this->desktop->canvas->endForcedFullRedraws();
}
/**
@@ -202,7 +195,7 @@ void PenTool::finish() {
sp_event_context_discard_delayed_snap_event(this);
if (this->npoints != 0) {
- pen_cancel(this);
+ this->_cancel();
}
FreehandBase::finish();
@@ -223,26 +216,31 @@ void PenTool::set(const Inkscape::Preferences::Entry& val) {
}
}
+bool PenTool::hasWaitingLPE() {
+ // note: waiting_LPE_type is defined in SPDrawContext
+ return (this->waiting_LPE != NULL ||
+ this->waiting_LPE_type != Inkscape::LivePathEffect::INVALID_LPE);
+}
+
/**
* Snaps new node relative to the previous node.
*/
-static void spdc_endpoint_snap(PenTool const *const pc, Geom::Point &p, guint const state)
-{
- if ((state & GDK_CONTROL_MASK) && !pc->polylines_paraxial) { //CTRL enables angular snapping
- if (pc->npoints > 0) {
- spdc_endpoint_snap_rotation(pc, p, pc->p[0], state);
+void PenTool::_endpointSnap(Geom::Point &p, guint const state) const {
+ if ((state & GDK_CONTROL_MASK) && !this->polylines_paraxial) { //CTRL enables angular snapping
+ if (this->npoints > 0) {
+ spdc_endpoint_snap_rotation(this, p, this->p[0], state);
}
} else {
// We cannot use shift here to disable snapping because the shift-key is already used
// to toggle the paraxial direction; if the user wants to disable snapping (s)he will
// have to use the %-key, the menu, or the snap toolbar
- if ((pc->npoints > 0) && pc->polylines_paraxial) {
+ if ((this->npoints > 0) && this->polylines_paraxial) {
// snap constrained
- pen_set_to_nearest_horiz_vert(pc, p, state, true);
+ this->_setToNearestHorizVert(p, state, true);
} else {
// snap freely
- boost::optional<Geom::Point> origin = pc->npoints > 0 ? pc->p[0] : boost::optional<Geom::Point>();
- spdc_endpoint_snap_free(pc, p, origin, state); // pass the origin, to allow for perpendicular / tangential snapping
+ boost::optional<Geom::Point> origin = this->npoints > 0 ? this->p[0] : boost::optional<Geom::Point>();
+ spdc_endpoint_snap_free(this, p, origin, state); // pass the origin, to allow for perpendicular / tangential snapping
}
}
}
@@ -250,30 +248,29 @@ static void spdc_endpoint_snap(PenTool const *const pc, Geom::Point &p, guint co
/**
* Snaps new node's handle relative to the new node.
*/
-static void spdc_endpoint_snap_handle(PenTool const *const pc, Geom::Point &p, guint const state)
-{
- g_return_if_fail(( pc->npoints == 2 ||
- pc->npoints == 5 ));
+void PenTool::_endpointSnapHandle(Geom::Point &p, guint const state) const {
+ g_return_if_fail(( this->npoints == 2 ||
+ this->npoints == 5 ));
if ((state & GDK_CONTROL_MASK)) { //CTRL enables angular snapping
- spdc_endpoint_snap_rotation(pc, p, pc->p[pc->npoints - 2], state);
+ spdc_endpoint_snap_rotation(this, p, this->p[this->npoints - 2], state);
} else {
if (!(state & GDK_SHIFT_MASK)) { //SHIFT disables all snapping, except the angular snapping above
- boost::optional<Geom::Point> origin = pc->p[pc->npoints - 2];
- spdc_endpoint_snap_free(pc, p, origin, state);
+ boost::optional<Geom::Point> origin = this->p[this->npoints - 2];
+ spdc_endpoint_snap_free(this, p, origin, state);
}
}
}
bool PenTool::item_handler(SPItem* item, GdkEvent* event) {
- gint ret = FALSE;
+ bool ret = false;
switch (event->type) {
case GDK_BUTTON_PRESS:
- ret = pen_handle_button_press(this, event->button);
+ ret = this->_handleButtonPress(event->button);
break;
case GDK_BUTTON_RELEASE:
- ret = pen_handle_button_release(this, event->button);
+ ret = this->_handleButtonRelease(event->button);
break;
default:
break;
@@ -290,27 +287,27 @@ bool PenTool::item_handler(SPItem* item, GdkEvent* event) {
* Callback to handle all pen events.
*/
bool PenTool::root_handler(GdkEvent* event) {
- gint ret = FALSE;
+ bool ret = false;
switch (event->type) {
case GDK_BUTTON_PRESS:
- ret = pen_handle_button_press(this, event->button);
+ ret = this->_handleButtonPress(event->button);
break;
case GDK_MOTION_NOTIFY:
- ret = pen_handle_motion_notify(this, event->motion);
+ ret = this->_handleMotionNotify(event->motion);
break;
case GDK_BUTTON_RELEASE:
- ret = pen_handle_button_release(this, event->button);
+ ret = this->_handleButtonRelease(event->button);
break;
case GDK_2BUTTON_PRESS:
- ret = pen_handle_2button_press(this, event->button);
+ ret = this->_handle2ButtonPress(event->button);
break;
case GDK_KEY_PRESS:
- ret = pen_handle_key_press(this, event);
+ ret = this->_handleKeyPress(event);
break;
default:
@@ -327,32 +324,29 @@ bool PenTool::root_handler(GdkEvent* event) {
/**
* Handle mouse button press event.
*/
-static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bevent)
-{
- if (pc->events_disabled) {
+bool PenTool::_handleButtonPress(GdkEventButton const &bevent) {
+ if (this->events_disabled) {
// skip event processing if events are disabled
- return FALSE;
+ return false;
}
- FreehandBase * const dc = SP_DRAW_CONTEXT(pc);
- SPDesktop * const desktop = dc->desktop;
Geom::Point const event_w(bevent.x, bevent.y);
Geom::Point event_dt(desktop->w2d(event_w));
- ToolBase *event_context = SP_EVENT_CONTEXT(pc);
- gint ret = FALSE;
- if (bevent.button == 1 && !event_context->space_panning
+ bool ret = false;
+
+ if (bevent.button == 1 && !this->space_panning
// make sure this is not the last click for a waiting LPE (otherwise we want to finish the path)
- && pc->expecting_clicks_for_LPE != 1) {
+ && this->expecting_clicks_for_LPE != 1) {
- if (Inkscape::have_viable_layer(desktop, dc->message_context) == false) {
- return TRUE;
+ if (Inkscape::have_viable_layer(desktop, this->message_context) == false) {
+ return true;
}
- if (!pc->grab ) {
+ if (!this->grab ) {
// Grab mouse, so release will not pass unnoticed
- pc->grab = SP_CANVAS_ITEM(desktop->acetate);
- sp_canvas_item_grab(pc->grab, ( GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK |
+ this->grab = SP_CANVAS_ITEM(desktop->acetate);
+ sp_canvas_item_grab(this->grab, ( GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK ),
NULL, bevent.time);
@@ -362,33 +356,33 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev
pen_within_tolerance = true;
// Test whether we hit any anchor.
- SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w);
+ SPDrawAnchor * const anchor = spdc_test_inside(this, event_w);
- switch (pc->mode) {
+ switch (this->mode) {
case PenTool::MODE_CLICK:
// In click mode we add point on release
- switch (pc->state) {
+ switch (this->state) {
case PenTool::POINT:
case PenTool::CONTROL:
case PenTool::CLOSE:
break;
case PenTool::STOP:
// This is allowed, if we just canceled curve
- pc->state = PenTool::POINT;
+ this->state = PenTool::POINT;
break;
default:
break;
}
break;
case PenTool::MODE_DRAG:
- switch (pc->state) {
+ switch (this->state) {
case PenTool::STOP:
// This is allowed, if we just canceled curve
case PenTool::POINT:
- if (pc->npoints == 0) {
+ if (this->npoints == 0) {
Geom::Point p;
- if ((bevent.state & GDK_CONTROL_MASK) && (pc->polylines_only || pc->polylines_paraxial)) {
+ if ((bevent.state & GDK_CONTROL_MASK) && (this->polylines_only || this->polylines_paraxial)) {
p = event_dt;
if (!(bevent.state & GDK_SHIFT_MASK)) {
SnapManager &m = desktop->namedview->snap_manager;
@@ -396,8 +390,8 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev
m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_NODE_HANDLE);
m.unSetup();
}
- spdc_create_single_dot(event_context, p, "/tools/freehand/pen", bevent.state);
- ret = TRUE;
+ spdc_create_single_dot(this, p, "/tools/freehand/pen", bevent.state);
+ ret = true;
break;
}
@@ -405,8 +399,8 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev
// distinction so that the case of a waiting LPE is treated separately
// Set start anchor
- pc->sa = anchor;
- if (anchor && !sp_pen_context_has_waiting_LPE(pc)) {
+ this->sa = anchor;
+ if (anchor && !this->hasWaitingLPE()) {
// Adjust point to anchor if needed; if we have a waiting LPE, we need
// a fresh path to be created so don't continue an existing one
p = anchor->dp;
@@ -416,7 +410,7 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev
// this curve is not combined with it (unless it is drawn from its
// anchor, which is handled by the sibling branch above)
Inkscape::Selection * const selection = sp_desktop_selection(desktop);
- if (!(bevent.state & GDK_SHIFT_MASK) || sp_pen_context_has_waiting_LPE(pc)) {
+ if (!(bevent.state & GDK_SHIFT_MASK) || this->hasWaitingLPE()) {
// if we have a waiting LPE, we need a fresh path to be created
// so don't append to an existing one
selection->clear();
@@ -427,38 +421,38 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev
// Create green anchor
p = event_dt;
- spdc_endpoint_snap(pc, p, bevent.state);
- pc->green_anchor = sp_draw_anchor_new(pc, pc->green_curve, TRUE, p);
+ this->_endpointSnap(p, bevent.state);
+ this->green_anchor = sp_draw_anchor_new(this, this->green_curve, TRUE, p);
}
- spdc_pen_set_initial_point(pc, p);
+ this->_setInitialPoint(p);
} else {
// Set end anchor
- pc->ea = anchor;
+ this->ea = anchor;
Geom::Point p;
if (anchor) {
p = anchor->dp;
// we hit an anchor, will finish the curve (either with or without closing)
// in release handler
- pc->state = PenTool::CLOSE;
+ this->state = PenTool::CLOSE;
- if (pc->green_anchor && pc->green_anchor->active) {
+ if (this->green_anchor && this->green_anchor->active) {
// we clicked on the current curve start, so close it even if
// we drag a handle away from it
- dc->green_closed = TRUE;
+ this->green_closed = TRUE;
}
- ret = TRUE;
+ ret = true;
break;
} else {
p = event_dt;
- spdc_endpoint_snap(pc, p, bevent.state); // Snap node only if not hitting anchor.
- spdc_pen_set_subsequent_point(pc, p, true);
+ this->_endpointSnap(p, bevent.state); // Snap node only if not hitting anchor.
+ this->_setSubsequentPoint(p, true);
}
}
- pc->state = pc->polylines_only ? PenTool::POINT : PenTool::CONTROL;
- ret = TRUE;
+ this->state = this->polylines_only ? PenTool::POINT : PenTool::CONTROL;
+ ret = true;
break;
case PenTool::CONTROL:
g_warning("Button down in CONTROL state");
@@ -473,26 +467,26 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev
default:
break;
}
- } else if (pc->expecting_clicks_for_LPE == 1 && pc->npoints != 0) {
+ } else if (this->expecting_clicks_for_LPE == 1 && this->npoints != 0) {
// when the last click for a waiting LPE occurs we want to finish the path
- spdc_pen_finish_segment(pc, event_dt, bevent.state);
- if (pc->green_closed) {
+ this->_finishSegment(event_dt, bevent.state);
+ if (this->green_closed) {
// finishing at the start anchor, close curve
- spdc_pen_finish(pc, TRUE);
+ this->_finish(true);
} else {
// finishing at some other anchor, finish curve but not close
- spdc_pen_finish(pc, FALSE);
+ this->_finish(false);
}
- ret = TRUE;
- } else if (bevent.button == 3 && pc->npoints != 0) {
+ ret = true;
+ } else if (bevent.button == 3 && this->npoints != 0) {
// right click - finish path
- spdc_pen_finish(pc, FALSE);
- ret = TRUE;
+ this->_finish(false);
+ ret = true;
}
- if (pc->expecting_clicks_for_LPE > 0) {
- --pc->expecting_clicks_for_LPE;
+ if (this->expecting_clicks_for_LPE > 0) {
+ --this->expecting_clicks_for_LPE;
}
return ret;
@@ -501,30 +495,26 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev
/**
* Handle motion_notify event.
*/
-static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &mevent)
-{
- gint ret = FALSE;
+bool PenTool::_handleMotionNotify(GdkEventMotion const &mevent) {
+ bool ret = false;
- ToolBase *event_context = SP_EVENT_CONTEXT(pc);
- SPDesktop * const dt = event_context->desktop;
-
- if (event_context->space_panning || mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) {
+ if (this->space_panning || mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) {
// allow scrolling
- return FALSE;
+ return false;
}
- if (pc->events_disabled) {
+ if (this->events_disabled) {
// skip motion events if pen events are disabled
- return FALSE;
+ return false;
}
- Geom::Point const event_w(mevent.x,
- mevent.y);
+ Geom::Point const event_w(mevent.x, mevent.y);
+
if (pen_within_tolerance) {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
gint const tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
if ( Geom::LInfty( event_w - pen_drag_origin_w ) < tolerance ) {
- return FALSE; // Do not drag if we're within tolerance from origin.
+ return false; // Do not drag if we're within tolerance from origin.
}
}
// Once the user has moved farther than tolerance from the original location
@@ -533,23 +523,23 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me
pen_within_tolerance = false;
// Find desktop coordinates
- Geom::Point p = dt->w2d(event_w);
+ Geom::Point p = desktop->w2d(event_w);
// Test, whether we hit any anchor
- SPDrawAnchor *anchor = spdc_test_inside(pc, event_w);
+ SPDrawAnchor *anchor = spdc_test_inside(this, event_w);
- switch (pc->mode) {
+ switch (this->mode) {
case PenTool::MODE_CLICK:
- switch (pc->state) {
+ switch (this->state) {
case PenTool::POINT:
- if ( pc->npoints != 0 ) {
+ if ( this->npoints != 0 ) {
// Only set point, if we are already appending
- spdc_endpoint_snap(pc, p, mevent.state);
- spdc_pen_set_subsequent_point(pc, p, true);
+ this->_endpointSnap(p, mevent.state);
+ this->_setSubsequentPoint(p, true);
ret = TRUE;
- } else if (!sp_event_context_knot_mouseover(pc)) {
- SnapManager &m = dt->namedview->snap_manager;
- m.setup(dt);
+ } else if (!this->sp_event_context_knot_mouseover()) {
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_NODE_HANDLE));
m.unSetup();
}
@@ -557,9 +547,9 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me
case PenTool::CONTROL:
case PenTool::CLOSE:
// Placing controls is last operation in CLOSE state
- spdc_endpoint_snap(pc, p, mevent.state);
- spdc_pen_set_ctrl(pc, p, mevent.state);
- ret = TRUE;
+ this->_endpointSnap(p, mevent.state);
+ this->_setCtrl(p, mevent.state);
+ ret = true;
break;
case PenTool::STOP:
// This is perfectly valid
@@ -569,38 +559,38 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me
}
break;
case PenTool::MODE_DRAG:
- switch (pc->state) {
+ switch (this->state) {
case PenTool::POINT:
- if ( pc->npoints > 0 ) {
+ if ( this->npoints > 0 ) {
// Only set point, if we are already appending
if (!anchor) { // Snap node only if not hitting anchor
- spdc_endpoint_snap(pc, p, mevent.state);
- spdc_pen_set_subsequent_point(pc, p, true, mevent.state);
+ this->_endpointSnap(p, mevent.state);
+ this->_setSubsequentPoint(p, true, mevent.state);
} else {
- spdc_pen_set_subsequent_point(pc, anchor->dp, false, mevent.state);
+ this->_setSubsequentPoint(anchor->dp, false, mevent.state);
}
- if (anchor && !pc->anchor_statusbar) {
- pc->message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Click</b> or <b>click and drag</b> to close and finish the path."));
- pc->anchor_statusbar = true;
- } else if (!anchor && pc->anchor_statusbar) {
- pc->message_context->clear();
- pc->anchor_statusbar = false;
+ if (anchor && !this->anchor_statusbar) {
+ this->message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Click</b> or <b>click and drag</b> to close and finish the path."));
+ this->anchor_statusbar = true;
+ } else if (!anchor && this->anchor_statusbar) {
+ this->message_context->clear();
+ this->anchor_statusbar = false;
}
- ret = TRUE;
+ ret = true;
} else {
- if (anchor && !pc->anchor_statusbar) {
- pc->message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Click</b> or <b>click and drag</b> to continue the path from this point."));
- pc->anchor_statusbar = true;
- } else if (!anchor && pc->anchor_statusbar) {
- pc->message_context->clear();
- pc->anchor_statusbar = false;
+ if (anchor && !this->anchor_statusbar) {
+ this->message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Click</b> or <b>click and drag</b> to continue the path from this point."));
+ this->anchor_statusbar = true;
+ } else if (!anchor && this->anchor_statusbar) {
+ this->message_context->clear();
+ this->anchor_statusbar = false;
}
- if (!sp_event_context_knot_mouseover(pc)) {
- SnapManager &m = dt->namedview->snap_manager;
- m.setup(dt);
+ if (!this->sp_event_context_knot_mouseover()) {
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_NODE_HANDLE));
m.unSetup();
}
@@ -611,23 +601,23 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me
// Placing controls is last operation in CLOSE state
// snap the handle
- spdc_endpoint_snap_handle(pc, p, mevent.state);
+ this->_endpointSnapHandle(p, mevent.state);
- if (!pc->polylines_only) {
- spdc_pen_set_ctrl(pc, p, mevent.state);
+ if (!this->polylines_only) {
+ this->_setCtrl(p, mevent.state);
} else {
- spdc_pen_set_ctrl(pc, pc->p[1], mevent.state);
+ this->_setCtrl(this->p[1], mevent.state);
}
gobble_motion_events(GDK_BUTTON1_MASK);
- ret = TRUE;
+ ret = true;
break;
case PenTool::STOP:
// This is perfectly valid
break;
default:
- if (!sp_event_context_knot_mouseover(pc)) {
- SnapManager &m = dt->namedview->snap_manager;
- m.setup(dt);
+ if (!this->sp_event_context_knot_mouseover()) {
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_NODE_HANDLE));
m.unSetup();
}
@@ -643,90 +633,86 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me
/**
* Handle mouse button release event.
*/
-static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &revent)
-{
- if (pc->events_disabled) {
+bool PenTool::_handleButtonRelease(GdkEventButton const &revent) {
+ if (this->events_disabled) {
// skip event processing if events are disabled
- return FALSE;
+ return false;
}
- gint ret = FALSE;
- ToolBase *event_context = SP_EVENT_CONTEXT(pc);
- if ( revent.button == 1 && !event_context->space_panning) {
+ bool ret = false;
- FreehandBase *dc = SP_DRAW_CONTEXT (pc);
+ if (revent.button == 1 && !this->space_panning) {
+ Geom::Point const event_w(revent.x, revent.y);
- Geom::Point const event_w(revent.x,
- revent.y);
// Find desktop coordinates
- Geom::Point p = pc->desktop->w2d(event_w);
+ Geom::Point p = this->desktop->w2d(event_w);
// Test whether we hit any anchor.
- SPDrawAnchor *anchor = spdc_test_inside(pc, event_w);
+ SPDrawAnchor *anchor = spdc_test_inside(this, event_w);
- switch (pc->mode) {
+ switch (this->mode) {
case PenTool::MODE_CLICK:
- switch (pc->state) {
+ switch (this->state) {
case PenTool::POINT:
- if ( pc->npoints == 0 ) {
+ if ( this->npoints == 0 ) {
// Start new thread only with button release
if (anchor) {
p = anchor->dp;
}
- pc->sa = anchor;
- spdc_pen_set_initial_point(pc, p);
+ this->sa = anchor;
+ this->_setInitialPoint(p);
} else {
// Set end anchor here
- pc->ea = anchor;
+ this->ea = anchor;
if (anchor) {
p = anchor->dp;
}
}
- pc->state = PenTool::CONTROL;
- ret = TRUE;
+ this->state = PenTool::CONTROL;
+ ret = true;
break;
case PenTool::CONTROL:
// End current segment
- spdc_endpoint_snap(pc, p, revent.state);
- spdc_pen_finish_segment(pc, p, revent.state);
- pc->state = PenTool::POINT;
- ret = TRUE;
+ this->_endpointSnap(p, revent.state);
+ this->_finishSegment(p, revent.state);
+ this->state = PenTool::POINT;
+ ret = true;
break;
case PenTool::CLOSE:
// End current segment
if (!anchor) { // Snap node only if not hitting anchor
- spdc_endpoint_snap(pc, p, revent.state);
+ this->_endpointSnap(p, revent.state);
}
- spdc_pen_finish_segment(pc, p, revent.state);
- spdc_pen_finish(pc, TRUE);
- pc->state = PenTool::POINT;
- ret = TRUE;
+ this->_finishSegment(p, revent.state);
+ this->_finish(true);
+ this->state = PenTool::POINT;
+ ret = true;
break;
case PenTool::STOP:
// This is allowed, if we just canceled curve
- pc->state = PenTool::POINT;
- ret = TRUE;
+ this->state = PenTool::POINT;
+ ret = true;
break;
default:
break;
}
break;
case PenTool::MODE_DRAG:
- switch (pc->state) {
+ switch (this->state) {
case PenTool::POINT:
case PenTool::CONTROL:
- spdc_endpoint_snap(pc, p, revent.state);
- spdc_pen_finish_segment(pc, p, revent.state);
+ this->_endpointSnap(p, revent.state);
+ this->_finishSegment(p, revent.state);
break;
case PenTool::CLOSE:
- spdc_endpoint_snap(pc, p, revent.state);
- spdc_pen_finish_segment(pc, p, revent.state);
- if (pc->green_closed) {
+ this->_endpointSnap(p, revent.state);
+ this->_finishSegment(p, revent.state);
+ if (this->green_closed) {
// finishing at the start anchor, close curve
- spdc_pen_finish(pc, TRUE);
+ this->_finish(true);
} else {
// finishing at some other anchor, finish curve but not close
- spdc_pen_finish(pc, FALSE);
+ this->_finish(false);
}
break;
case PenTool::STOP:
@@ -735,37 +721,36 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r
default:
break;
}
- pc->state = PenTool::POINT;
- ret = TRUE;
+ this->state = PenTool::POINT;
+ ret = true;
break;
default:
break;
}
- if (pc->grab) {
+ if (this->grab) {
// Release grab now
- sp_canvas_item_ungrab(pc->grab, revent.time);
- pc->grab = NULL;
+ sp_canvas_item_ungrab(this->grab, revent.time);
+ this->grab = NULL;
}
- ret = TRUE;
+ ret = true;
- dc->green_closed = FALSE;
+ this->green_closed = FALSE;
}
// TODO: can we be sure that the path was created correctly?
// TODO: should we offer an option to collect the clicks in a list?
- if (pc->expecting_clicks_for_LPE == 0 && sp_pen_context_has_waiting_LPE(pc)) {
- sp_pen_context_set_polyline_mode(pc);
+ if (this->expecting_clicks_for_LPE == 0 && this->hasWaitingLPE()) {
+ this->setPolylineMode();
- ToolBase *ec = SP_EVENT_CONTEXT(pc);
- Inkscape::Selection *selection = sp_desktop_selection (ec->desktop);
+ Inkscape::Selection *selection = sp_desktop_selection(this->desktop);
- if (pc->waiting_LPE) {
+ if (this->waiting_LPE) {
// we have an already created LPE waiting for a path
- pc->waiting_LPE->acceptParamPath(SP_PATH(selection->singleItem()));
- selection->add(SP_OBJECT(pc->waiting_item));
- pc->waiting_LPE = NULL;
+ this->waiting_LPE->acceptParamPath(SP_PATH(selection->singleItem()));
+ selection->add(this->waiting_item);
+ this->waiting_LPE = NULL;
} else {
// the case that we need to create a new LPE and apply it to the just-drawn path is
// handled in spdc_check_for_and_apply_waiting_LPE() in draw-context.cpp
@@ -775,186 +760,209 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r
return ret;
}
-static gint pen_handle_2button_press(PenTool *const pc, GdkEventButton const &bevent)
-{
- gint ret = FALSE;
+bool PenTool::_handle2ButtonPress(GdkEventButton const &bevent) {
+ bool ret = false;
// only end on LMB double click. Otherwise horizontal scrolling causes ending of the path
- if (pc->npoints != 0 && bevent.button == 1) {
- spdc_pen_finish(pc, FALSE);
- ret = TRUE;
+ if (this->npoints != 0 && bevent.button == 1) {
+ this->_finish(FALSE);
+ ret = true;
}
return ret;
}
-static void pen_redraw_all (PenTool *const pc)
-{
+void PenTool::_redrawAll() {
// green
- if (pc->green_bpaths) {
+ if (this->green_bpaths) {
// remove old piecewise green canvasitems
- while (pc->green_bpaths) {
- sp_canvas_item_destroy(SP_CANVAS_ITEM(pc->green_bpaths->data));
- pc->green_bpaths = g_slist_remove(pc->green_bpaths, pc->green_bpaths->data);
+ while (this->green_bpaths) {
+ sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data));
+ this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data);
}
// one canvas bpath for all of green_curve
- SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(pc->desktop), pc->green_curve);
- sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
+ SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), this->green_curve);
+ sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), this->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cshape), 0, SP_WIND_RULE_NONZERO);
- pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape);
+ this->green_bpaths = g_slist_prepend(this->green_bpaths, cshape);
}
- if (pc->green_anchor)
- SP_CTRL(pc->green_anchor->ctrl)->moveto(pc->green_anchor->dp);
+ if (this->green_anchor)
+ SP_CTRL(this->green_anchor->ctrl)->moveto(this->green_anchor->dp);
- pc->red_curve->reset();
- pc->red_curve->moveto(pc->p[0]);
- pc->red_curve->curveto(pc->p[1], pc->p[2], pc->p[3]);
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve);
+ this->red_curve->reset();
+ this->red_curve->moveto(this->p[0]);
+ this->red_curve->curveto(this->p[1], this->p[2], this->p[3]);
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve);
// handles
- if (pc->p[0] != pc->p[1]) {
- SP_CTRL(pc->c1)->moveto(pc->p[1]);
- pc->cl1->setCoords(pc->p[0], pc->p[1]);
- sp_canvas_item_show(pc->c1);
- sp_canvas_item_show(pc->cl1);
+ if (this->p[0] != this->p[1]) {
+ SP_CTRL(this->c1)->moveto(this->p[1]);
+ this->cl1->setCoords(this->p[0], this->p[1]);
+ sp_canvas_item_show(this->c1);
+ sp_canvas_item_show(this->cl1);
} else {
- sp_canvas_item_hide(pc->c1);
- sp_canvas_item_hide(pc->cl1);
+ sp_canvas_item_hide(this->c1);
+ sp_canvas_item_hide(this->cl1);
}
- Geom::Curve const * last_seg = pc->green_curve->last_segment();
+ Geom::Curve const * last_seg = this->green_curve->last_segment();
if (last_seg) {
Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const *>( last_seg );
if ( cubic &&
- (*cubic)[2] != pc->p[0] )
+ (*cubic)[2] != this->p[0] )
{
Geom::Point p2 = (*cubic)[2];
- SP_CTRL(pc->c0)->moveto(p2);
- pc->cl0->setCoords(p2, pc->p[0]);
- sp_canvas_item_show(pc->c0);
- sp_canvas_item_show(pc->cl0);
+ SP_CTRL(this->c0)->moveto(p2);
+ this->cl0->setCoords(p2, this->p[0]);
+ sp_canvas_item_show(this->c0);
+ sp_canvas_item_show(this->cl0);
} else {
- sp_canvas_item_hide(pc->c0);
- sp_canvas_item_hide(pc->cl0);
+ sp_canvas_item_hide(this->c0);
+ sp_canvas_item_hide(this->cl0);
}
}
}
-static void pen_lastpoint_move (PenTool *const pc, gdouble x, gdouble y)
-{
- if (pc->npoints != 5)
+void PenTool::_lastpointMove(gdouble x, gdouble y) {
+ if (this->npoints != 5)
return;
// green
- if (!pc->green_curve->is_empty()) {
- pc->green_curve->last_point_additive_move( Geom::Point(x,y) );
+ if (!this->green_curve->is_empty()) {
+ this->green_curve->last_point_additive_move( Geom::Point(x,y) );
} else {
// start anchor too
- if (pc->green_anchor) {
- pc->green_anchor->dp += Geom::Point(x, y);
+ if (this->green_anchor) {
+ this->green_anchor->dp += Geom::Point(x, y);
}
}
// red
- pc->p[0] += Geom::Point(x, y);
- pc->p[1] += Geom::Point(x, y);
- pen_redraw_all(pc);
+ this->p[0] += Geom::Point(x, y);
+ this->p[1] += Geom::Point(x, y);
+ this->_redrawAll();
}
-static void pen_lastpoint_move_screen (PenTool *const pc, gdouble x, gdouble y)
-{
- pen_lastpoint_move (pc, x / pc->desktop->current_zoom(), y / pc->desktop->current_zoom());
+void PenTool::_lastpointMoveScreen(gdouble x, gdouble y) {
+ this->_lastpointMove(x / this->desktop->current_zoom(), y / this->desktop->current_zoom());
}
-static void pen_lastpoint_tocurve (PenTool *const pc)
-{
- if (pc->npoints != 5)
+void PenTool::_lastpointToCurve() {
+ if (this->npoints != 5)
return;
- Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const *>( pc->green_curve->last_segment() );
+ Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const *>( this->green_curve->last_segment() );
if ( cubic ) {
- pc->p[1] = pc->p[0] + (Geom::Point)( (*cubic)[3] - (*cubic)[2] );
+ this->p[1] = this->p[0] + (Geom::Point)( (*cubic)[3] - (*cubic)[2] );
} else {
- pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]);
+ this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]);
}
- pen_redraw_all(pc);
+ this->_redrawAll();
}
-static void pen_lastpoint_toline (PenTool *const pc)
-{
- if (pc->npoints != 5)
+void PenTool::_lastpointToLine() {
+ if (this->npoints != 5)
return;
- pc->p[1] = pc->p[0];
+ this->p[1] = this->p[0];
- pen_redraw_all(pc);
+ this->_redrawAll();
}
-static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event)
-{
-
- gint ret = FALSE;
+bool PenTool::_handleKeyPress(GdkEvent *event) {
+ bool ret = false;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
gdouble const nudge = prefs->getDoubleLimited("/options/nudgedistance/value", 2, 0, 1000, "px"); // in px
switch (get_group0_keyval (&event->key)) {
-
case GDK_KEY_Left: // move last point left
case GDK_KEY_KP_Left:
if (!MOD__CTRL(event)) { // not ctrl
if (MOD__ALT(event)) { // alt
- if (MOD__SHIFT(event)) pen_lastpoint_move_screen(pc, -10, 0); // shift
- else pen_lastpoint_move_screen(pc, -1, 0); // no shift
+ if (MOD__SHIFT(event)) {
+ this->_lastpointMoveScreen(-10, 0); // shift
+ }
+ else {
+ this->_lastpointMoveScreen(-1, 0); // no shift
+ }
}
else { // no alt
- if (MOD__SHIFT(event)) pen_lastpoint_move(pc, -10*nudge, 0); // shift
- else pen_lastpoint_move(pc, -nudge, 0); // no shift
+ if (MOD__SHIFT(event)) {
+ this->_lastpointMove(-10*nudge, 0); // shift
+ }
+ else {
+ this->_lastpointMove(-nudge, 0); // no shift
+ }
}
- ret = TRUE;
+ ret = true;
}
break;
case GDK_KEY_Up: // move last point up
case GDK_KEY_KP_Up:
if (!MOD__CTRL(event)) { // not ctrl
if (MOD__ALT(event)) { // alt
- if (MOD__SHIFT(event)) pen_lastpoint_move_screen(pc, 0, 10); // shift
- else pen_lastpoint_move_screen(pc, 0, 1); // no shift
+ if (MOD__SHIFT(event)) {
+ this->_lastpointMoveScreen(0, 10); // shift
+ }
+ else {
+ this->_lastpointMoveScreen(0, 1); // no shift
+ }
}
else { // no alt
- if (MOD__SHIFT(event)) pen_lastpoint_move(pc, 0, 10*nudge); // shift
- else pen_lastpoint_move(pc, 0, nudge); // no shift
+ if (MOD__SHIFT(event)) {
+ this->_lastpointMove(0, 10*nudge); // shift
+ }
+ else {
+ this->_lastpointMove(0, nudge); // no shift
+ }
}
- ret = TRUE;
+ ret = true;
}
break;
case GDK_KEY_Right: // move last point right
case GDK_KEY_KP_Right:
if (!MOD__CTRL(event)) { // not ctrl
if (MOD__ALT(event)) { // alt
- if (MOD__SHIFT(event)) pen_lastpoint_move_screen(pc, 10, 0); // shift
- else pen_lastpoint_move_screen(pc, 1, 0); // no shift
+ if (MOD__SHIFT(event)) {
+ this->_lastpointMoveScreen(10, 0); // shift
+ }
+ else {
+ this->_lastpointMoveScreen(1, 0); // no shift
+ }
}
else { // no alt
- if (MOD__SHIFT(event)) pen_lastpoint_move(pc, 10*nudge, 0); // shift
- else pen_lastpoint_move(pc, nudge, 0); // no shift
+ if (MOD__SHIFT(event)) {
+ this->_lastpointMove(10*nudge, 0); // shift
+ }
+ else {
+ this->_lastpointMove(nudge, 0); // no shift
+ }
}
- ret = TRUE;
+ ret = true;
}
break;
case GDK_KEY_Down: // move last point down
case GDK_KEY_KP_Down:
if (!MOD__CTRL(event)) { // not ctrl
if (MOD__ALT(event)) { // alt
- if (MOD__SHIFT(event)) pen_lastpoint_move_screen(pc, 0, -10); // shift
- else pen_lastpoint_move_screen(pc, 0, -1); // no shift
+ if (MOD__SHIFT(event)) {
+ this->_lastpointMoveScreen(0, -10); // shift
+ }
+ else {
+ this->_lastpointMoveScreen(0, -1); // no shift
+ }
}
else { // no alt
- if (MOD__SHIFT(event)) pen_lastpoint_move(pc, 0, -10*nudge); // shift
- else pen_lastpoint_move(pc, 0, -nudge); // no shift
+ if (MOD__SHIFT(event)) {
+ this->_lastpointMove(0, -10*nudge); // shift
+ }
+ else {
+ this->_lastpointMove(0, -nudge); // no shift
+ }
}
- ret = TRUE;
+ ret = true;
}
break;
@@ -995,92 +1003,92 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event)
case GDK_KEY_U:
case GDK_KEY_u:
if (MOD__SHIFT_ONLY(event)) {
- pen_lastpoint_tocurve(pc);
- ret = TRUE;
+ this->_lastpointToCurve();
+ ret = true;
}
break;
case GDK_KEY_L:
case GDK_KEY_l:
if (MOD__SHIFT_ONLY(event)) {
- pen_lastpoint_toline(pc);
- ret = TRUE;
+ this->_lastpointToLine();
+ ret = true;
}
break;
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
- if (pc->npoints != 0) {
- spdc_pen_finish(pc, FALSE);
- ret = TRUE;
+ if (this->npoints != 0) {
+ this->_finish(false);
+ ret = true;
}
break;
case GDK_KEY_Escape:
- if (pc->npoints != 0) {
+ if (this->npoints != 0) {
// if drawing, cancel, otherwise pass it up for deselecting
- pen_cancel (pc);
- ret = TRUE;
+ this->_cancel ();
+ ret = true;
}
break;
case GDK_KEY_z:
case GDK_KEY_Z:
- if (MOD__CTRL_ONLY(event) && pc->npoints != 0) {
+ if (MOD__CTRL_ONLY(event) && this->npoints != 0) {
// if drawing, cancel, otherwise pass it up for undo
- pen_cancel (pc);
- ret = TRUE;
+ this->_cancel ();
+ ret = true;
}
break;
case GDK_KEY_g:
case GDK_KEY_G:
if (MOD__SHIFT_ONLY(event)) {
- sp_selection_to_guides(SP_EVENT_CONTEXT(pc)->desktop);
+ sp_selection_to_guides(this->desktop);
ret = true;
}
break;
case GDK_KEY_BackSpace:
case GDK_KEY_Delete:
case GDK_KEY_KP_Delete:
- if ( pc->green_curve->is_empty() || (pc->green_curve->last_segment() == NULL) ) {
- if (!pc->red_curve->is_empty()) {
- pen_cancel (pc);
- ret = TRUE;
+ if ( this->green_curve->is_empty() || (this->green_curve->last_segment() == NULL) ) {
+ if (!this->red_curve->is_empty()) {
+ this->_cancel ();
+ ret = true;
} else {
// do nothing; this event should be handled upstream
}
} else {
// Reset red curve
- pc->red_curve->reset();
+ this->red_curve->reset();
// Destroy topmost green bpath
- if (pc->green_bpaths) {
- if (pc->green_bpaths->data)
- sp_canvas_item_destroy(SP_CANVAS_ITEM(pc->green_bpaths->data));
- pc->green_bpaths = g_slist_remove(pc->green_bpaths, pc->green_bpaths->data);
+ if (this->green_bpaths) {
+ if (this->green_bpaths->data)
+ sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data));
+ this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data);
}
// Get last segment
- if ( pc->green_curve->is_empty() ) {
+ if ( this->green_curve->is_empty() ) {
g_warning("pen_handle_key_press, case GDK_KP_Delete: Green curve is empty");
break;
}
// The code below assumes that pc->green_curve has only ONE path !
- Geom::Curve const * crv = pc->green_curve->last_segment();
- pc->p[0] = crv->initialPoint();
+ Geom::Curve const * crv = this->green_curve->last_segment();
+ this->p[0] = crv->initialPoint();
if ( Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const *>(crv)) {
- pc->p[1] = (*cubic)[1];
+ this->p[1] = (*cubic)[1];
} else {
- pc->p[1] = pc->p[0];
+ this->p[1] = this->p[0];
}
- Geom::Point const pt(( pc->npoints < 4
+ Geom::Point const pt(( this->npoints < 4
? (Geom::Point)(crv->finalPoint())
- : pc->p[3] ));
- pc->npoints = 2;
- pc->green_curve->backspace();
- sp_canvas_item_hide(pc->c0);
- sp_canvas_item_hide(pc->c1);
- sp_canvas_item_hide(pc->cl0);
- sp_canvas_item_hide(pc->cl1);
- pc->state = PenTool::POINT;
- spdc_pen_set_subsequent_point(pc, pt, true);
+ : this->p[3] ));
+ this->npoints = 2;
+ this->green_curve->backspace();
+ sp_canvas_item_hide(this->c0);
+ sp_canvas_item_hide(this->c1);
+ sp_canvas_item_hide(this->cl0);
+ sp_canvas_item_hide(this->cl1);
+ this->state = PenTool::POINT;
+ this->_setSubsequentPoint(pt, true);
pen_last_paraxial_dir = !pen_last_paraxial_dir;
- ret = TRUE;
+ ret = true;
}
break;
default:
@@ -1089,40 +1097,38 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event)
return ret;
}
-static void spdc_reset_colors(PenTool *pc)
-{
+void PenTool::_resetColors() {
// Red
- pc->red_curve->reset();
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL);
+ this->red_curve->reset();
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), NULL);
// Blue
- pc->blue_curve->reset();
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), NULL);
+ this->blue_curve->reset();
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue_bpath), NULL);
// Green
- while (pc->green_bpaths) {
- sp_canvas_item_destroy(SP_CANVAS_ITEM(pc->green_bpaths->data));
- pc->green_bpaths = g_slist_remove(pc->green_bpaths, pc->green_bpaths->data);
+ while (this->green_bpaths) {
+ sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data));
+ this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data);
}
- pc->green_curve->reset();
- if (pc->green_anchor) {
- pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor);
+ this->green_curve->reset();
+ if (this->green_anchor) {
+ this->green_anchor = sp_draw_anchor_destroy(this->green_anchor);
}
- pc->sa = NULL;
- pc->ea = NULL;
- pc->npoints = 0;
- pc->red_curve_is_valid = false;
+ this->sa = NULL;
+ this->ea = NULL;
+ this->npoints = 0;
+ this->red_curve_is_valid = false;
}
-static void spdc_pen_set_initial_point(PenTool *const pc, Geom::Point const p)
-{
- g_assert( pc->npoints == 0 );
+void PenTool::_setInitialPoint(Geom::Point const p) {
+ g_assert( this->npoints == 0 );
- pc->p[0] = p;
- pc->p[1] = p;
- pc->npoints = 2;
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL);
+ this->p[0] = p;
+ this->p[1] = p;
+ this->npoints = 2;
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), NULL);
- pc->desktop->canvas->forceFullRedrawAfterInterruptions(5);
+ this->desktop->canvas->forceFullRedrawAfterInterruptions(5);
}
/**
@@ -1130,14 +1136,12 @@ static void spdc_pen_set_initial_point(PenTool *const pc, Geom::Point const p)
* This type of message always shows angle/distance as the last
* two parameters ("angle %3.2f&#176;, distance %s").
*/
-static void spdc_pen_set_angle_distance_status_message(PenTool *const pc, Geom::Point const p, int pc_point_to_compare, gchar const *message)
-{
- g_assert(pc != NULL);
+void PenTool::_setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_to_compare, gchar const *message) {
+ g_assert(this != NULL);
g_assert((pc_point_to_compare == 0) || (pc_point_to_compare == 3)); // exclude control handles
g_assert(message != NULL);
- SPDesktop *desktop = SP_EVENT_CONTEXT(pc)->desktop;
- Geom::Point rel = p - pc->p[pc_point_to_compare];
+ Geom::Point rel = p - this->p[pc_point_to_compare];
Inkscape::Util::Quantity q = Inkscape::Util::Quantity(Geom::L2(rel), "px");
GString *dist = g_string_new(q.string(desktop->namedview->doc_units).c_str());
double angle = atan2(rel[Geom::Y], rel[Geom::X]) * 180 / M_PI;
@@ -1149,192 +1153,176 @@ static void spdc_pen_set_angle_distance_status_message(PenTool *const pc, Geom::
}
}
- pc->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, message, angle, dist->str);
+ this->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, message, angle, dist->str);
g_string_free(dist, FALSE);
}
-static void spdc_pen_set_subsequent_point(PenTool *const pc, Geom::Point const p, bool statusbar, guint status)
-{
- g_assert( pc->npoints != 0 );
+void PenTool::_setSubsequentPoint(Geom::Point const p, bool statusbar, guint status) {
+ g_assert( this->npoints != 0 );
// todo: Check callers to see whether 2 <= npoints is guaranteed.
- pc->p[2] = p;
- pc->p[3] = p;
- pc->p[4] = p;
- pc->npoints = 5;
- pc->red_curve->reset();
+ this->p[2] = p;
+ this->p[3] = p;
+ this->p[4] = p;
+ this->npoints = 5;
+ this->red_curve->reset();
bool is_curve;
- pc->red_curve->moveto(pc->p[0]);
- if (pc->polylines_paraxial && !statusbar) {
+ this->red_curve->moveto(this->p[0]);
+ if (this->polylines_paraxial && !statusbar) {
// we are drawing horizontal/vertical lines and hit an anchor;
- Geom::Point const origin = pc->p[0];
+ Geom::Point const origin = this->p[0];
// if the previous point and the anchor are not aligned either horizontally or vertically...
if ((abs(p[Geom::X] - origin[Geom::X]) > 1e-9) && (abs(p[Geom::Y] - origin[Geom::Y]) > 1e-9)) {
// ...then we should draw an L-shaped path, consisting of two paraxial segments
Geom::Point intermed = p;
- pen_set_to_nearest_horiz_vert(pc, intermed, status, false);
- pc->red_curve->lineto(intermed);
+ this->_setToNearestHorizVert(intermed, status, false);
+ this->red_curve->lineto(intermed);
}
- pc->red_curve->lineto(p);
+ this->red_curve->lineto(p);
is_curve = false;
} else {
// one of the 'regular' modes
- if (pc->p[1] != pc->p[0]) {
- pc->red_curve->curveto(pc->p[1], p, p);
+ if (this->p[1] != this->p[0]) {
+ this->red_curve->curveto(this->p[1], p, p);
is_curve = true;
} else {
- pc->red_curve->lineto(p);
+ this->red_curve->lineto(p);
is_curve = false;
}
}
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve);
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve);
if (statusbar) {
gchar *message = is_curve ?
_("<b>Curve segment</b>: angle %3.2f&#176;, distance %s; with <b>Ctrl</b> to snap angle, <b>Enter</b> to finish the path" ):
_("<b>Line segment</b>: angle %3.2f&#176;, distance %s; with <b>Ctrl</b> to snap angle, <b>Enter</b> to finish the path");
- spdc_pen_set_angle_distance_status_message(pc, p, 0, message);
+ this->_setAngleDistanceStatusMessage(p, 0, message);
}
}
-static void spdc_pen_set_ctrl(PenTool *const pc, Geom::Point const p, guint const state)
-{
- sp_canvas_item_show(pc->c1);
- sp_canvas_item_show(pc->cl1);
-
- if ( pc->npoints == 2 ) {
- pc->p[1] = p;
- sp_canvas_item_hide(pc->c0);
- sp_canvas_item_hide(pc->cl0);
- SP_CTRL(pc->c1)->moveto(pc->p[1]);
- pc->cl1->setCoords(pc->p[0], pc->p[1]);
-
- spdc_pen_set_angle_distance_status_message(pc, p, 0, _("<b>Curve handle</b>: angle %3.2f&#176;, length %s; with <b>Ctrl</b> to snap angle"));
- } else if ( pc->npoints == 5 ) {
- pc->p[4] = p;
- sp_canvas_item_show(pc->c0);
- sp_canvas_item_show(pc->cl0);
+void PenTool::_setCtrl(Geom::Point const p, guint const state) {
+ sp_canvas_item_show(this->c1);
+ sp_canvas_item_show(this->cl1);
+
+ if ( this->npoints == 2 ) {
+ this->p[1] = p;
+ sp_canvas_item_hide(this->c0);
+ sp_canvas_item_hide(this->cl0);
+ SP_CTRL(this->c1)->moveto(this->p[1]);
+ this->cl1->setCoords(this->p[0], this->p[1]);
+
+ this->_setAngleDistanceStatusMessage(p, 0, _("<b>Curve handle</b>: angle %3.2f&#176;, length %s; with <b>Ctrl</b> to snap angle"));
+ } else if ( this->npoints == 5 ) {
+ this->p[4] = p;
+ sp_canvas_item_show(this->c0);
+ sp_canvas_item_show(this->cl0);
bool is_symm = false;
- if ( ( ( pc->mode == PenTool::MODE_CLICK ) && ( state & GDK_CONTROL_MASK ) ) ||
- ( ( pc->mode == PenTool::MODE_DRAG ) && !( state & GDK_SHIFT_MASK ) ) ) {
- Geom::Point delta = p - pc->p[3];
- pc->p[2] = pc->p[3] - delta;
+ if ( ( ( this->mode == PenTool::MODE_CLICK ) && ( state & GDK_CONTROL_MASK ) ) ||
+ ( ( this->mode == PenTool::MODE_DRAG ) && !( state & GDK_SHIFT_MASK ) ) ) {
+ Geom::Point delta = p - this->p[3];
+ this->p[2] = this->p[3] - delta;
is_symm = true;
- pc->red_curve->reset();
- pc->red_curve->moveto(pc->p[0]);
- pc->red_curve->curveto(pc->p[1], pc->p[2], pc->p[3]);
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve);
+ this->red_curve->reset();
+ this->red_curve->moveto(this->p[0]);
+ this->red_curve->curveto(this->p[1], this->p[2], this->p[3]);
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve);
}
- SP_CTRL(pc->c0)->moveto(pc->p[2]);
- pc->cl0 ->setCoords(pc->p[3], pc->p[2]);
- SP_CTRL(pc->c1)->moveto(pc->p[4]);
- pc->cl1->setCoords(pc->p[3], pc->p[4]);
+ SP_CTRL(this->c0)->moveto(this->p[2]);
+ this->cl0 ->setCoords(this->p[3], this->p[2]);
+ SP_CTRL(this->c1)->moveto(this->p[4]);
+ this->cl1->setCoords(this->p[3], this->p[4]);
gchar *message = is_symm ?
_("<b>Curve handle, symmetric</b>: angle %3.2f&#176;, length %s; with <b>Ctrl</b> to snap angle, with <b>Shift</b> to move this handle only") :
_("<b>Curve handle</b>: angle %3.2f&#176;, length %s; with <b>Ctrl</b> to snap angle, with <b>Shift</b> to move this handle only");
- spdc_pen_set_angle_distance_status_message(pc, p, 3, message);
+ this->_setAngleDistanceStatusMessage(p, 3, message);
} else {
- g_warning("Something bad happened - npoints is %d", pc->npoints);
+ g_warning("Something bad happened - npoints is %d", this->npoints);
}
}
-static void spdc_pen_finish_segment(PenTool *const pc, Geom::Point const p, guint const state)
-{
- if (pc->polylines_paraxial) {
- pen_last_paraxial_dir = pen_next_paraxial_direction(pc, p, pc->p[0], state);
+void PenTool::_finishSegment(Geom::Point const p, guint const state) {
+ if (this->polylines_paraxial) {
+ pen_last_paraxial_dir = this->nextParaxialDirection(p, this->p[0], state);
}
- ++pc->num_clicks;
+ ++this->num_clicks;
- if (!pc->red_curve->is_empty()) {
- pc->green_curve->append_continuous(pc->red_curve, 0.0625);
- SPCurve *curve = pc->red_curve->copy();
+ if (!this->red_curve->is_empty()) {
+ this->green_curve->append_continuous(this->red_curve, 0.0625);
+ SPCurve *curve = this->red_curve->copy();
/// \todo fixme:
- SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(pc->desktop), curve);
+ SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), curve);
curve->unref();
- sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
+ sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), this->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
- pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape);
+ this->green_bpaths = g_slist_prepend(this->green_bpaths, cshape);
- pc->p[0] = pc->p[3];
- pc->p[1] = pc->p[4];
- pc->npoints = 2;
+ this->p[0] = this->p[3];
+ this->p[1] = this->p[4];
+ this->npoints = 2;
- pc->red_curve->reset();
+ this->red_curve->reset();
}
}
-static void spdc_pen_finish(PenTool *const pc, gboolean const closed)
-{
- if (pc->expecting_clicks_for_LPE > 1) {
+void PenTool::_finish(gboolean const closed) {
+ if (this->expecting_clicks_for_LPE > 1) {
// don't let the path be finished before we have collected the required number of mouse clicks
return;
}
- pc->num_clicks = 0;
+ this->num_clicks = 0;
- pen_disable_events(pc);
+ this->_disableEvents();
- SPDesktop *const desktop = pc->desktop;
- pc->message_context->clear();
+ this->message_context->clear();
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Drawing finished"));
- pc->red_curve->reset();
- spdc_concat_colors_and_flush(pc, closed);
- pc->sa = NULL;
- pc->ea = NULL;
+ this->red_curve->reset();
+ spdc_concat_colors_and_flush(this, closed);
+ this->sa = NULL;
+ this->ea = NULL;
- pc->npoints = 0;
- pc->state = PenTool::POINT;
+ this->npoints = 0;
+ this->state = PenTool::POINT;
- sp_canvas_item_hide(pc->c0);
- sp_canvas_item_hide(pc->c1);
- sp_canvas_item_hide(pc->cl0);
- sp_canvas_item_hide(pc->cl1);
+ sp_canvas_item_hide(this->c0);
+ sp_canvas_item_hide(this->c1);
+ sp_canvas_item_hide(this->cl0);
+ sp_canvas_item_hide(this->cl1);
- if (pc->green_anchor) {
- pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor);
+ if (this->green_anchor) {
+ this->green_anchor = sp_draw_anchor_destroy(this->green_anchor);
}
+ this->desktop->canvas->endForcedFullRedraws();
- pc->desktop->canvas->endForcedFullRedraws();
-
- pen_enable_events(pc);
+ this->_enableEvents();
}
-static void pen_disable_events(PenTool *const pc) {
- pc->events_disabled++;
+void PenTool::_disableEvents() {
+ this->events_disabled = true;
}
-static void pen_enable_events(PenTool *const pc) {
- g_return_if_fail(pc->events_disabled != 0);
+void PenTool::_enableEvents() {
+ g_return_if_fail(this->events_disabled != 0);
- pc->events_disabled--;
+ this->events_disabled = false;
}
-void sp_pen_context_wait_for_LPE_mouse_clicks(PenTool *pc, Inkscape::LivePathEffect::EffectType effect_type,
- unsigned int num_clicks, bool use_polylines)
-{
+void PenTool::waitForLPEMouseClicks(Inkscape::LivePathEffect::EffectType effect_type, unsigned int num_clicks, bool use_polylines) {
if (effect_type == Inkscape::LivePathEffect::INVALID_LPE)
return;
- pc->waiting_LPE_type = effect_type;
- pc->expecting_clicks_for_LPE = num_clicks;
- pc->polylines_only = use_polylines;
- pc->polylines_paraxial = false; // TODO: think if this is correct for all cases
-}
-
-void sp_pen_context_cancel_waiting_for_LPE(PenTool *pc)
-{
- pc->waiting_LPE_type = Inkscape::LivePathEffect::INVALID_LPE;
- pc->expecting_clicks_for_LPE = 0;
- sp_pen_context_set_polyline_mode(pc);
+ this->waiting_LPE_type = effect_type;
+ this->expecting_clicks_for_LPE = num_clicks;
+ this->polylines_only = use_polylines;
+ this->polylines_paraxial = false; // TODO: think if this is correct for all cases
}
-static int pen_next_paraxial_direction(const PenTool *const pc,
- Geom::Point const &pt, Geom::Point const &origin, guint state) {
+int PenTool::nextParaxialDirection(Geom::Point const &pt, Geom::Point const &origin, guint state) const {
//
// after the first mouse click we determine whether the mouse pointer is closest to a
// horizontal or vertical segment; for all subsequent mouse clicks, we use the direction
@@ -1344,7 +1332,7 @@ static int pen_next_paraxial_direction(const PenTool *const pc,
// (on first mouse release), in which case num_clicks immediately becomes 1.
// if (pc->num_clicks == 0) {
- if (pc->green_curve->is_empty()) {
+ if (this->green_curve->is_empty()) {
// first mouse click
double dist_h = fabs(pt[Geom::X] - origin[Geom::X]);
double dist_v = fabs(pt[Geom::Y] - origin[Geom::Y]);
@@ -1357,11 +1345,10 @@ static int pen_next_paraxial_direction(const PenTool *const pc,
}
}
-void pen_set_to_nearest_horiz_vert(const PenTool *const pc, Geom::Point &pt, guint const state, bool snap)
-{
- Geom::Point const origin = pc->p[0];
+void PenTool::_setToNearestHorizVert(Geom::Point &pt, guint const state, bool snap) const {
+ Geom::Point const origin = this->p[0];
- int next_dir = pen_next_paraxial_direction(pc, pt, origin, state);
+ int next_dir = this->nextParaxialDirection(pt, origin, state);
if (!snap) {
if (next_dir == 0) {
@@ -1376,13 +1363,13 @@ void pen_set_to_nearest_horiz_vert(const PenTool *const pc, Geom::Point &pt, gui
Inkscape::Snapper::SnapConstraint cl(origin, next_dir ? Geom::Point(0, 1) : Geom::Point(1, 0));
// Snap along the constraint line; if we didn't snap then still the constraint will be applied
- SnapManager &m = pc->desktop->namedview->snap_manager;
+ SnapManager &m = this->desktop->namedview->snap_manager;
- Inkscape::Selection *selection = sp_desktop_selection (pc->desktop);
+ Inkscape::Selection *selection = sp_desktop_selection (this->desktop);
// selection->singleItem() is the item that is currently being drawn. This item will not be snapped to (to avoid self-snapping)
// TODO: Allow snapping to the stationary parts of the item, and only ignore the last segment
- m.setup(pc->desktop, true, selection->singleItem());
+ m.setup(this->desktop, true, selection->singleItem());
m.constrainedSnapReturnByRef(pt, Inkscape::SNAPSOURCE_NODE_HANDLE, cl);
m.unSetup();
}
diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h
index 4452dbd68..4dec7b4fe 100644
--- a/src/ui/tools/pen-tool.h
+++ b/src/ui/tools/pen-tool.h
@@ -23,6 +23,7 @@ namespace Tools {
class PenTool : public FreehandBase {
public:
PenTool();
+ PenTool(gchar const *const *cursor_shape, gint hot_x, gint hot_y);
virtual ~PenTool();
enum Mode {
@@ -60,32 +61,58 @@ public:
SPCtrlLine *cl0;
SPCtrlLine *cl1;
- unsigned int events_disabled : 1;
+ bool events_disabled;
static const std::string prefsPath;
virtual const std::string& getPrefsPath();
+ int nextParaxialDirection(Geom::Point const &pt, Geom::Point const &origin, guint state) const;
+ void setPolylineMode();
+ bool hasWaitingLPE();
+ void waitForLPEMouseClicks(Inkscape::LivePathEffect::EffectType effect_type, unsigned int num_clicks, bool use_polylines = true);
+
protected:
virtual void setup();
virtual void finish();
virtual void set(const Inkscape::Preferences::Entry& val);
virtual bool root_handler(GdkEvent* event);
virtual bool item_handler(SPItem* item, GdkEvent* event);
-};
-inline bool sp_pen_context_has_waiting_LPE(PenTool *pc) {
- // note: waiting_LPE_type is defined in SPDrawContext
- return (pc->waiting_LPE != NULL ||
- pc->waiting_LPE_type != Inkscape::LivePathEffect::INVALID_LPE);
-}
+private:
+ bool _handleButtonPress(GdkEventButton const &bevent);
+ bool _handleMotionNotify(GdkEventMotion const &mevent);
+ bool _handleButtonRelease(GdkEventButton const &revent);
+ bool _handle2ButtonPress(GdkEventButton const &bevent);
+ bool _handleKeyPress(GdkEvent *event);
+
+ void _setInitialPoint(Geom::Point const p);
+ void _setSubsequentPoint(Geom::Point const p, bool statusbar, guint status = 0);
+ void _setCtrl(Geom::Point const p, guint state);
+ void _finishSegment(Geom::Point p, guint state);
+
+ void _finish(gboolean closed);
+
+ void _resetColors();
-void sp_pen_context_set_polyline_mode(PenTool *const pc);
-void sp_pen_context_wait_for_LPE_mouse_clicks(PenTool *pc, Inkscape::LivePathEffect::EffectType effect_type,
- unsigned int num_clicks, bool use_polylines = true);
-void sp_pen_context_cancel_waiting_for_LPE(PenTool *pc);
-void sp_pen_context_put_into_waiting_mode(SPDesktop *desktop, Inkscape::LivePathEffect::EffectType effect_type,
- unsigned int num_clicks, bool use_polylines = true);
+ void _disableEvents();
+ void _enableEvents();
+
+ void _setToNearestHorizVert(Geom::Point &pt, guint const state, bool snap) const;
+
+ void _setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_to_compare, gchar const *message);
+
+ void _lastpointToLine();
+ void _lastpointToCurve();
+ void _lastpointMoveScreen(gdouble x, gdouble y);
+ void _lastpointMove(gdouble x, gdouble y);
+ void _redrawAll();
+
+ void _endpointSnapHandle(Geom::Point &p, guint const state) const;
+ void _endpointSnap(Geom::Point &p, guint const state) const;
+
+ void _cancel();
+};
}
}
diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp
index 52779d551..fb4e82c32 100644
--- a/src/ui/tools/pencil-tool.cpp
+++ b/src/ui/tools/pencil-tool.cpp
@@ -26,7 +26,6 @@
#include "draw-anchor.h"
#include "message-stack.h"
#include "message-context.h"
-#include "modifier-fns.h"
#include "sp-path.h"
#include "preferences.h"
#include "snap.h"
@@ -45,25 +44,12 @@
#include "display/curve.h"
#include "livarot/Path.h"
#include "tool-factory.h"
+#include "ui/tool/event-utils.h"
namespace Inkscape {
namespace UI {
namespace Tools {
-static gint pencil_handle_button_press(PencilTool *const pc, GdkEventButton const &bevent);
-static gint pencil_handle_motion_notify(PencilTool *const pc, GdkEventMotion const &mevent);
-static gint pencil_handle_button_release(PencilTool *const pc, GdkEventButton const &revent);
-static gint pencil_handle_key_press(PencilTool *const pc, guint const keyval, guint const state);
-static gint pencil_handle_key_release(PencilTool *const pc, guint const keyval, guint const state);
-
-static void spdc_set_startpoint(PencilTool *pc, Geom::Point const &p);
-static void spdc_set_endpoint(PencilTool *pc, Geom::Point const &p);
-static void spdc_finish_endpoint(PencilTool *pc);
-static void spdc_add_freehand_point(PencilTool *pc, Geom::Point const &p, guint state);
-static void fit_and_split(PencilTool *pc);
-static void interpolate(PencilTool *pc);
-static void sketch_interpolate(PencilTool *pc);
-
static Geom::Point pencil_drag_origin_w(0, 0);
static bool pencil_within_tolerance = false;
@@ -83,20 +69,15 @@ const std::string& PencilTool::getPrefsPath() {
const std::string PencilTool::prefsPath = "/tools/freehand/pencil";
-PencilTool::PencilTool() :
- FreehandBase(),
- p(),
- npoints(0),
- state(SP_PENCIL_CONTEXT_IDLE),
- req_tangent(0,0),
- is_drawing(false),
- ps(),
- sketch_interpolation(Geom::Piecewise<Geom::D2<Geom::SBasis> >())// since PencilTool is not properly constructed...
+PencilTool::PencilTool()
+ : FreehandBase(cursor_pencil_xpm, 4, 4)
+ , p()
+ , npoints(0)
+ , state(SP_PENCIL_CONTEXT_IDLE)
+ , req_tangent(0, 0)
+ , is_drawing(false)
+ , sketch_n(0)
{
- this->cursor_shape = cursor_pencil_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
- this->sketch_n = 0;
}
void PencilTool::setup() {
@@ -115,19 +96,17 @@ PencilTool::~PencilTool() {
}
/** Snaps new node relative to the previous node. */
-static void
-spdc_endpoint_snap(PencilTool const *pc, Geom::Point &p, guint const state)
-{
+void PencilTool::_endpointSnap(Geom::Point &p, guint const state) {
if ((state & GDK_CONTROL_MASK)) { //CTRL enables constrained snapping
- if (pc->npoints > 0) {
- spdc_endpoint_snap_rotation(pc, p, pc->p[0], state);
+ if (this->npoints > 0) {
+ spdc_endpoint_snap_rotation(this, p, this->p[0], state);
}
} else {
if (!(state & GDK_SHIFT_MASK)) { //SHIFT disables all snapping, except the angular snapping above
//After all, the user explicitely asked for angular snapping by
//pressing CTRL
- boost::optional<Geom::Point> origin = pc->npoints > 0 ? pc->p[0] : boost::optional<Geom::Point>();
- spdc_endpoint_snap_free(pc, p, origin, state);
+ boost::optional<Geom::Point> origin = this->npoints > 0 ? this->p[0] : boost::optional<Geom::Point>();
+ spdc_endpoint_snap_free(this, p, origin, state);
}
}
}
@@ -136,27 +115,27 @@ spdc_endpoint_snap(PencilTool const *pc, Geom::Point &p, guint const state)
* Callback for handling all pencil context events.
*/
bool PencilTool::root_handler(GdkEvent* event) {
- gint ret = FALSE;
+ bool ret = false;
switch (event->type) {
case GDK_BUTTON_PRESS:
- ret = pencil_handle_button_press(this, event->button);
+ ret = this->_handleButtonPress(event->button);
break;
case GDK_MOTION_NOTIFY:
- ret = pencil_handle_motion_notify(this, event->motion);
+ ret = this->_handleMotionNotify(event->motion);
break;
case GDK_BUTTON_RELEASE:
- ret = pencil_handle_button_release(this, event->button);
+ ret = this->_handleButtonRelease(event->button);
break;
case GDK_KEY_PRESS:
- ret = pencil_handle_key_press(this, get_group0_keyval (&event->key), event->key.state);
+ ret = this->_handleKeyPress(event->key);
break;
case GDK_KEY_RELEASE:
- ret = pencil_handle_key_release(this, get_group0_keyval (&event->key), event->key.state);
+ ret = this->_handleKeyRelease(event->key);
break;
default:
@@ -170,25 +149,20 @@ bool PencilTool::root_handler(GdkEvent* event) {
return ret;
}
-static gint
-pencil_handle_button_press(PencilTool *const pc, GdkEventButton const &bevent)
-{
- gint ret = FALSE;
- ToolBase *event_context = SP_EVENT_CONTEXT(pc);
- if ( bevent.button == 1 && !event_context->space_panning) {
+bool PencilTool::_handleButtonPress(GdkEventButton const &bevent) {
+ bool ret = false;
- FreehandBase *dc = SP_DRAW_CONTEXT (pc);
- SPDesktop *desktop = dc->desktop;
+ if ( bevent.button == 1 && !this->space_panning) {
Inkscape::Selection *selection = sp_desktop_selection(desktop);
- if (Inkscape::have_viable_layer(desktop, dc->message_context) == false) {
- return TRUE;
+ if (Inkscape::have_viable_layer(desktop, this->message_context) == false) {
+ return true;
}
- if (!pc->grab) {
+ if (!this->grab) {
/* Grab mouse, so release will not pass unnoticed */
- pc->grab = SP_CANVAS_ITEM(desktop->acetate);
- sp_canvas_item_grab(pc->grab, ( GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK |
+ this->grab = SP_CANVAS_ITEM(desktop->acetate);
+ sp_canvas_item_grab(this->grab, ( GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK ),
NULL, bevent.time);
@@ -197,18 +171,18 @@ pencil_handle_button_press(PencilTool *const pc, GdkEventButton const &bevent)
Geom::Point const button_w(bevent.x, bevent.y);
/* Find desktop coordinates */
- Geom::Point p = pc->desktop->w2d(button_w);
+ Geom::Point p = this->desktop->w2d(button_w);
/* Test whether we hit any anchor. */
- SPDrawAnchor *anchor = spdc_test_inside(pc, button_w);
+ SPDrawAnchor *anchor = spdc_test_inside(this, button_w);
pencil_drag_origin_w = Geom::Point(bevent.x,bevent.y);
pencil_within_tolerance = true;
- switch (pc->state) {
+ switch (this->state) {
case SP_PENCIL_CONTEXT_ADDLINE:
/* Current segment will be finished with release */
- ret = TRUE;
+ ret = true;
break;
default:
/* Set first point of sequence */
@@ -219,7 +193,7 @@ pencil_handle_button_press(PencilTool *const pc, GdkEventButton const &bevent)
if (!(bevent.state & GDK_SHIFT_MASK)) {
m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_NODE_HANDLE);
}
- spdc_create_single_dot(event_context, p, "/tools/freehand/pencil", bevent.state);
+ spdc_create_single_dot(this, p, "/tools/freehand/pencil", bevent.state);
m.unSetup();
ret = true;
break;
@@ -242,56 +216,52 @@ pencil_handle_button_press(PencilTool *const pc, GdkEventButton const &bevent)
}
m.unSetup();
}
- pc->sa = anchor;
- spdc_set_startpoint(pc, p);
- ret = TRUE;
+ this->sa = anchor;
+ this->_setStartpoint(p);
+ ret = true;
break;
}
- pc->is_drawing = true;
+ this->is_drawing = true;
}
return ret;
}
-static gint
-pencil_handle_motion_notify(PencilTool *const pc, GdkEventMotion const &mevent)
-{
- SPDesktop *const dt = pc->desktop;
-
+bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) {
if ((mevent.state & GDK_CONTROL_MASK) && (mevent.state & GDK_BUTTON1_MASK)) {
// mouse was accidentally moved during Ctrl+click;
// ignore the motion and create a single point
- pc->is_drawing = false;
- return TRUE;
+ this->is_drawing = false;
+ return true;
}
- gint ret = FALSE;
- ToolBase *event_context = SP_EVENT_CONTEXT(pc);
- if (event_context->space_panning || mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) {
+ bool ret = false;
+
+ if (this->space_panning || (mevent.state & GDK_BUTTON2_MASK) || (mevent.state & GDK_BUTTON3_MASK)) {
// allow scrolling
- return FALSE;
+ return false;
}
- if ( ( mevent.state & GDK_BUTTON1_MASK ) && !pc->grab && pc->is_drawing) {
+ if ( ( mevent.state & GDK_BUTTON1_MASK ) && !this->grab && this->is_drawing) {
/* Grab mouse, so release will not pass unnoticed */
- pc->grab = SP_CANVAS_ITEM(dt->acetate);
- sp_canvas_item_grab(pc->grab, ( GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK |
+ this->grab = SP_CANVAS_ITEM(desktop->acetate);
+ sp_canvas_item_grab(this->grab, ( GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK ),
NULL, mevent.time);
}
/* Find desktop coordinates */
- Geom::Point p = dt->w2d(Geom::Point(mevent.x, mevent.y));
+ Geom::Point p = desktop->w2d(Geom::Point(mevent.x, mevent.y));
/* Test whether we hit any anchor. */
- SPDrawAnchor *anchor = spdc_test_inside(pc, Geom::Point(mevent.x, mevent.y));
+ SPDrawAnchor *anchor = spdc_test_inside(this, Geom::Point(mevent.x, mevent.y));
if (pencil_within_tolerance) {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
gint const tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
if ( Geom::LInfty( Geom::Point(mevent.x,mevent.y) - pencil_drag_origin_w ) < tolerance ) {
- return FALSE; // Do not drag if we're within tolerance from origin.
+ return false; // Do not drag if we're within tolerance from origin.
}
}
@@ -300,73 +270,73 @@ pencil_handle_motion_notify(PencilTool *const pc, GdkEventMotion const &mevent)
// motion notify coordinates as given (no snapping back to origin)
pencil_within_tolerance = false;
- switch (pc->state) {
+ switch (this->state) {
case SP_PENCIL_CONTEXT_ADDLINE:
/* Set red endpoint */
if (anchor) {
p = anchor->dp;
} else {
Geom::Point ptnr(p);
- spdc_endpoint_snap(pc, ptnr, mevent.state);
+ this->_endpointSnap(ptnr, mevent.state);
p = ptnr;
}
- spdc_set_endpoint(pc, p);
- ret = TRUE;
+ this->_setEndpoint(p);
+ ret = true;
break;
default:
/* We may be idle or already freehand */
- if ( mevent.state & GDK_BUTTON1_MASK && pc->is_drawing ) {
- if (pc->state == SP_PENCIL_CONTEXT_IDLE) {
- sp_event_context_discard_delayed_snap_event(event_context);
+ if ( (mevent.state & GDK_BUTTON1_MASK) && this->is_drawing ) {
+ if (this->state == SP_PENCIL_CONTEXT_IDLE) {
+ sp_event_context_discard_delayed_snap_event(this);
}
- pc->state = SP_PENCIL_CONTEXT_FREEHAND;
+ this->state = SP_PENCIL_CONTEXT_FREEHAND;
- if ( !pc->sa && !pc->green_anchor ) {
+ if ( !this->sa && !this->green_anchor ) {
/* Create green anchor */
- pc->green_anchor = sp_draw_anchor_new(pc, pc->green_curve, TRUE, pc->p[0]);
+ this->green_anchor = sp_draw_anchor_new(this, this->green_curve, TRUE, this->p[0]);
}
if (anchor) {
p = anchor->dp;
}
- if ( pc->npoints != 0) { // buttonpress may have happened before we entered draw context!
- if (pc->ps.empty()) {
+ if ( this->npoints != 0) { // buttonpress may have happened before we entered draw context!
+ if (this->ps.empty()) {
// Only in freehand mode we have to add the first point also to pc->ps (apparently)
// - We cannot add this point in spdc_set_startpoint, because we only need it for freehand
// - We cannot do this in the button press handler because at that point we don't know yet
// wheter we're going into freehand mode or not
- pc->ps.push_back(pc->p[0]);
+ this->ps.push_back(this->p[0]);
}
- spdc_add_freehand_point(pc, p, mevent.state);
- ret = TRUE;
+ this->_addFreehandPoint(p, mevent.state);
+ ret = true;
}
- if (anchor && !pc->anchor_statusbar) {
- pc->message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Release</b> here to close and finish the path."));
- pc->anchor_statusbar = true;
- } else if (!anchor && pc->anchor_statusbar) {
- pc->message_context->clear();
- pc->anchor_statusbar = false;
+ if (anchor && !this->anchor_statusbar) {
+ this->message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Release</b> here to close and finish the path."));
+ this->anchor_statusbar = true;
+ } else if (!anchor && this->anchor_statusbar) {
+ this->message_context->clear();
+ this->anchor_statusbar = false;
} else if (!anchor) {
- pc->message_context->set(Inkscape::NORMAL_MESSAGE, _("Drawing a freehand path"));
+ this->message_context->set(Inkscape::NORMAL_MESSAGE, _("Drawing a freehand path"));
}
} else {
- if (anchor && !pc->anchor_statusbar) {
- pc->message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> to continue the path from this point."));
- pc->anchor_statusbar = true;
- } else if (!anchor && pc->anchor_statusbar) {
- pc->message_context->clear();
- pc->anchor_statusbar = false;
+ if (anchor && !this->anchor_statusbar) {
+ this->message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> to continue the path from this point."));
+ this->anchor_statusbar = true;
+ } else if (!anchor && this->anchor_statusbar) {
+ this->message_context->clear();
+ this->anchor_statusbar = false;
}
}
// Show the pre-snap indicator to communicate to the user where we would snap to if he/she were to
// a) press the mousebutton to start a freehand drawing, or
// b) release the mousebutton to finish a freehand drawing
- if (!sp_event_context_knot_mouseover(pc)) {
- SnapManager &m = dt->namedview->snap_manager;
- m.setup(dt);
+ if (!this->sp_event_context_knot_mouseover()) {
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_NODE_HANDLE));
m.unSetup();
}
@@ -375,59 +345,52 @@ pencil_handle_motion_notify(PencilTool *const pc, GdkEventMotion const &mevent)
return ret;
}
-static gint
-pencil_handle_button_release(PencilTool *const pc, GdkEventButton const &revent)
-{
- gint ret = FALSE;
-
- ToolBase *event_context = SP_EVENT_CONTEXT(pc);
- if ( revent.button == 1 && pc->is_drawing && !event_context->space_panning) {
- SPDesktop *const dt = pc->desktop;
+bool PencilTool::_handleButtonRelease(GdkEventButton const &revent) {
+ bool ret = false;
- pc->is_drawing = false;
+ if ( revent.button == 1 && this->is_drawing && !this->space_panning) {
+ this->is_drawing = false;
/* Find desktop coordinates */
- Geom::Point p = dt->w2d(Geom::Point(revent.x, revent.y));
+ Geom::Point p = desktop->w2d(Geom::Point(revent.x, revent.y));
/* Test whether we hit any anchor. */
- SPDrawAnchor *anchor = spdc_test_inside(pc, Geom::Point(revent.x,
- revent.y));
+ SPDrawAnchor *anchor = spdc_test_inside(this, Geom::Point(revent.x, revent.y));
- switch (pc->state) {
+ switch (this->state) {
case SP_PENCIL_CONTEXT_IDLE:
/* Releasing button in idle mode means single click */
/* We have already set up start point/anchor in button_press */
if (!(revent.state & GDK_CONTROL_MASK)) {
// Ctrl+click creates a single point so only set context in ADDLINE mode when Ctrl isn't pressed
- pc->state = SP_PENCIL_CONTEXT_ADDLINE;
+ this->state = SP_PENCIL_CONTEXT_ADDLINE;
}
- ret = TRUE;
+ ret = true;
break;
case SP_PENCIL_CONTEXT_ADDLINE:
/* Finish segment now */
if (anchor) {
p = anchor->dp;
} else {
- spdc_endpoint_snap(pc, p, revent.state);
+ this->_endpointSnap(p, revent.state);
}
- pc->ea = anchor;
- spdc_set_endpoint(pc, p);
- spdc_finish_endpoint(pc);
- pc->state = SP_PENCIL_CONTEXT_IDLE;
- sp_event_context_discard_delayed_snap_event(event_context);
- ret = TRUE;
+ this->ea = anchor;
+ this->_setEndpoint(p);
+ this->_finishEndpoint();
+ this->state = SP_PENCIL_CONTEXT_IDLE;
+ sp_event_context_discard_delayed_snap_event(this);
+ ret = true;
break;
case SP_PENCIL_CONTEXT_FREEHAND:
if (revent.state & GDK_MOD1_MASK) {
/* sketch mode: interpolate the sketched path and improve the current output path with the new interpolation. don't finish sketch */
+ this->_sketchInterpolate();
- sketch_interpolate(pc);
-
- if (pc->green_anchor) {
- pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor);
+ if (this->green_anchor) {
+ this->green_anchor = sp_draw_anchor_destroy(this->green_anchor);
}
- pc->state = SP_PENCIL_CONTEXT_SKETCH;
+ this->state = SP_PENCIL_CONTEXT_SKETCH;
} else {
/* Finish segment now */
/// \todo fixme: Clean up what follows (Lauris)
@@ -435,114 +398,111 @@ pencil_handle_button_release(PencilTool *const pc, GdkEventButton const &revent)
p = anchor->dp;
} else {
Geom::Point p_end = p;
- spdc_endpoint_snap(pc, p_end, revent.state);
+ this->_endpointSnap(p_end, revent.state);
if (p_end != p) {
// then we must have snapped!
- spdc_add_freehand_point(pc, p_end, revent.state);
+ this->_addFreehandPoint(p_end, revent.state);
}
}
- pc->ea = anchor;
+ this->ea = anchor;
/* Write curves to object */
- dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing freehand"));
+ desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing freehand"));
- interpolate(pc);
- spdc_concat_colors_and_flush(pc, FALSE);
- pc->sa = NULL;
- pc->ea = NULL;
- if (pc->green_anchor) {
- pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor);
+ this->_interpolate();
+ spdc_concat_colors_and_flush(this, FALSE);
+ this->sa = NULL;
+ this->ea = NULL;
+ if (this->green_anchor) {
+ this->green_anchor = sp_draw_anchor_destroy(this->green_anchor);
}
- pc->state = SP_PENCIL_CONTEXT_IDLE;
+ this->state = SP_PENCIL_CONTEXT_IDLE;
// reset sketch mode too
- pc->sketch_n = 0;
+ this->sketch_n = 0;
}
- ret = TRUE;
+ ret = true;
break;
case SP_PENCIL_CONTEXT_SKETCH:
default:
break;
}
- if (pc->grab) {
+ if (this->grab) {
/* Release grab now */
- sp_canvas_item_ungrab(pc->grab, revent.time);
- pc->grab = NULL;
+ sp_canvas_item_ungrab(this->grab, revent.time);
+ this->grab = NULL;
}
- ret = TRUE;
+ ret = true;
}
return ret;
}
-static void
-pencil_cancel (PencilTool *const pc)
-{
- if (pc->grab) {
+void PencilTool::_cancel() {
+ if (this->grab) {
/* Release grab now */
- sp_canvas_item_ungrab(pc->grab, 0);
- pc->grab = NULL;
+ sp_canvas_item_ungrab(this->grab, 0);
+ this->grab = NULL;
}
- pc->is_drawing = false;
- pc->state = SP_PENCIL_CONTEXT_IDLE;
- sp_event_context_discard_delayed_snap_event(SP_EVENT_CONTEXT(pc));
-
- pc->red_curve->reset();
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL);
- while (pc->green_bpaths) {
- sp_canvas_item_destroy(SP_CANVAS_ITEM(pc->green_bpaths->data));
- pc->green_bpaths = g_slist_remove(pc->green_bpaths, pc->green_bpaths->data);
+ this->is_drawing = false;
+ this->state = SP_PENCIL_CONTEXT_IDLE;
+ sp_event_context_discard_delayed_snap_event(this);
+
+ this->red_curve->reset();
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), NULL);
+ while (this->green_bpaths) {
+ sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data));
+ this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data);
}
- pc->green_curve->reset();
- if (pc->green_anchor) {
- pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor);
+ this->green_curve->reset();
+ if (this->green_anchor) {
+ this->green_anchor = sp_draw_anchor_destroy(this->green_anchor);
}
- pc->message_context->clear();
- pc->message_context->flash(Inkscape::NORMAL_MESSAGE, _("Drawing cancelled"));
+ this->message_context->clear();
+ this->message_context->flash(Inkscape::NORMAL_MESSAGE, _("Drawing cancelled"));
- pc->desktop->canvas->endForcedFullRedraws();
+ this->desktop->canvas->endForcedFullRedraws();
}
-static gint
-pencil_handle_key_press(PencilTool *const pc, guint const keyval, guint const state)
-{
- gint ret = FALSE;
- switch (keyval) {
+bool PencilTool::_handleKeyPress(GdkEventKey const &event) {
+ bool ret = false;
+
+ switch (get_group0_keyval(&event)) {
case GDK_KEY_Up:
case GDK_KEY_Down:
case GDK_KEY_KP_Up:
case GDK_KEY_KP_Down:
// Prevent the zoom field from activation.
- if (!mod_ctrl_only(state)) {
- ret = TRUE;
+ if (!Inkscape::UI::held_only_control(event)) {
+ ret = true;
}
break;
case GDK_KEY_Escape:
- if (pc->npoints != 0) {
+ if (this->npoints != 0) {
// if drawing, cancel, otherwise pass it up for deselecting
- if (pc->state != SP_PENCIL_CONTEXT_IDLE) {
- pencil_cancel (pc);
- ret = TRUE;
+ if (this->state != SP_PENCIL_CONTEXT_IDLE) {
+ this->_cancel();
+ ret = true;
}
}
break;
case GDK_KEY_z:
case GDK_KEY_Z:
- if (mod_ctrl_only(state) && pc->npoints != 0) {
+ if (Inkscape::UI::held_only_control(event) && this->npoints != 0) {
// if drawing, cancel, otherwise pass it up for undo
- if (pc->state != SP_PENCIL_CONTEXT_IDLE) {
- pencil_cancel (pc);
- ret = TRUE;
+ if (this->state != SP_PENCIL_CONTEXT_IDLE) {
+ this->_cancel();
+ ret = true;
}
}
break;
case GDK_KEY_g:
case GDK_KEY_G:
- if (mod_shift_only(state)) {
- sp_selection_to_guides(SP_EVENT_CONTEXT(pc)->desktop);
+ if (Inkscape::UI::held_only_shift(event)) {
+ sp_selection_to_guides(this->desktop);
ret = true;
}
break;
@@ -550,8 +510,8 @@ pencil_handle_key_press(PencilTool *const pc, guint const keyval, guint const st
case GDK_KEY_Alt_R:
case GDK_KEY_Meta_L:
case GDK_KEY_Meta_R:
- if (pc->state == SP_PENCIL_CONTEXT_IDLE) {
- pc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("<b>Sketch mode</b>: holding <b>Alt</b> interpolates between sketched paths. Release <b>Alt</b> to finalize."));
+ if (this->state == SP_PENCIL_CONTEXT_IDLE) {
+ this->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("<b>Sketch mode</b>: holding <b>Alt</b> interpolates between sketched paths. Release <b>Alt</b> to finalize."));
}
break;
default:
@@ -560,27 +520,26 @@ pencil_handle_key_press(PencilTool *const pc, guint const keyval, guint const st
return ret;
}
-static gint
-pencil_handle_key_release(PencilTool *const pc, guint const keyval, guint const /*state*/)
-{
- gint ret = FALSE;
- switch (keyval) {
+bool PencilTool::_handleKeyRelease(GdkEventKey const &event) {
+ bool ret = false;
+
+ switch (get_group0_keyval(&event)) {
case GDK_KEY_Alt_L:
case GDK_KEY_Alt_R:
case GDK_KEY_Meta_L:
case GDK_KEY_Meta_R:
- if (pc->state == SP_PENCIL_CONTEXT_SKETCH) {
- spdc_concat_colors_and_flush(pc, FALSE);
- pc->sketch_n = 0;
- pc->sa = NULL;
- pc->ea = NULL;
- if (pc->green_anchor) {
- pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor);
+ if (this->state == SP_PENCIL_CONTEXT_SKETCH) {
+ spdc_concat_colors_and_flush(this, false);
+ this->sketch_n = 0;
+ this->sa = NULL;
+ this->ea = NULL;
+ if (this->green_anchor) {
+ this->green_anchor = sp_draw_anchor_destroy(this->green_anchor);
}
- pc->state = SP_PENCIL_CONTEXT_IDLE;
- sp_event_context_discard_delayed_snap_event(SP_EVENT_CONTEXT(pc));
- pc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing freehand sketch"));
- ret = TRUE;
+ this->state = SP_PENCIL_CONTEXT_IDLE;
+ sp_event_context_discard_delayed_snap_event(this);
+ this->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing freehand sketch"));
+ ret = true;
}
break;
default:
@@ -592,13 +551,11 @@ pencil_handle_key_release(PencilTool *const pc, guint const keyval, guint const
/**
* Reset points and set new starting point.
*/
-static void
-spdc_set_startpoint(PencilTool *const pc, Geom::Point const &p)
-{
- pc->npoints = 0;
- pc->red_curve_is_valid = false;
+void PencilTool::_setStartpoint(Geom::Point const &p) {
+ this->npoints = 0;
+ this->red_curve_is_valid = false;
if (in_svg_plane(p)) {
- pc->p[pc->npoints++] = p;
+ this->p[this->npoints++] = p;
}
}
@@ -612,31 +569,29 @@ spdc_set_startpoint(PencilTool *const pc, Geom::Point const &p)
* Number of points is (re)set to 2 always, 2nd point is modified.
* We change RED curve.
*/
-static void
-spdc_set_endpoint(PencilTool *const pc, Geom::Point const &p)
-{
- if (pc->npoints == 0) {
+void PencilTool::_setEndpoint(Geom::Point const &p) {
+ if (this->npoints == 0) {
return;
/* May occur if first point wasn't in SVG plane (e.g. weird w2d transform, perhaps from bad
* zoom setting).
*/
}
- g_return_if_fail( pc->npoints > 0 );
+ g_return_if_fail( this->npoints > 0 );
- pc->red_curve->reset();
- if ( ( p == pc->p[0] )
+ this->red_curve->reset();
+ if ( ( p == this->p[0] )
|| !in_svg_plane(p) )
{
- pc->npoints = 1;
+ this->npoints = 1;
} else {
- pc->p[1] = p;
- pc->npoints = 2;
+ this->p[1] = p;
+ this->npoints = 2;
- pc->red_curve->moveto(pc->p[0]);
- pc->red_curve->lineto(pc->p[1]);
- pc->red_curve_is_valid = true;
+ this->red_curve->moveto(this->p[0]);
+ this->red_curve->lineto(this->p[1]);
+ this->red_curve_is_valid = true;
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve);
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve);
}
}
@@ -647,35 +602,30 @@ spdc_set_endpoint(PencilTool *const pc, Geom::Point const &p)
* fixme: I'd like remove red reset from concat colors (lauris).
* Still not sure, how it will make most sense.
*/
-static void
-spdc_finish_endpoint(PencilTool *const pc)
-{
- if ( ( pc->red_curve->is_empty() )
- || ( *(pc->red_curve->first_point()) == *(pc->red_curve->second_point()) ) )
+void PencilTool::_finishEndpoint() {
+ if ( ( this->red_curve->is_empty() )
+ || ( *(this->red_curve->first_point()) == *(this->red_curve->second_point()) ) )
{
- pc->red_curve->reset();
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL);
+ this->red_curve->reset();
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), NULL);
} else {
/* Write curves to object. */
- spdc_concat_colors_and_flush(pc, FALSE);
- pc->sa = NULL;
- pc->ea = NULL;
+ spdc_concat_colors_and_flush(this, FALSE);
+ this->sa = NULL;
+ this->ea = NULL;
}
}
+void PencilTool::_addFreehandPoint(Geom::Point const &p, guint /*state*/) {
+ g_assert( this->npoints > 0 );
+ g_return_if_fail(unsigned(this->npoints) < G_N_ELEMENTS(this->p));
-static void
-spdc_add_freehand_point(PencilTool *pc, Geom::Point const &p, guint /*state*/)
-{
- g_assert( pc->npoints > 0 );
- g_return_if_fail(unsigned(pc->npoints) < G_N_ELEMENTS(pc->p));
-
- if ( ( p != pc->p[ pc->npoints - 1 ] )
+ if ( ( p != this->p[ this->npoints - 1 ] )
&& in_svg_plane(p) )
{
- pc->ps.push_back(p);
- pc->p[pc->npoints++] = p;
- fit_and_split(pc);
+ this->ps.push_back(p);
+ this->p[this->npoints++] = p;
+ this->_fitAndSplit();
}
}
@@ -685,218 +635,202 @@ square(double const x)
return x * x;
}
-static void
-interpolate(PencilTool *pc)
-{
- if ( pc->ps.size() <= 1 ) {
+void PencilTool::_interpolate() {
+ if ( this->ps.size() <= 1 ) {
return;
}
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4;
- double const tolerance_sq = 0.02 * square( pc->desktop->w2d().descrim() *
- tol) * exp(0.2*tol - 2);
+ double const tolerance_sq = 0.02 * square(this->desktop->w2d().descrim() * tol) * exp(0.2 * tol - 2);
- g_assert(is_zero(pc->req_tangent)
- || is_unit_vector(pc->req_tangent));
- Geom::Point const tHatEnd(0, 0);
+ g_assert(is_zero(this->req_tangent) || is_unit_vector(this->req_tangent));
- guint n_points = pc->ps.size();
- pc->green_curve->reset();
- pc->red_curve->reset();
- pc->red_curve_is_valid = false;
+ this->green_curve->reset();
+ this->red_curve->reset();
+ this->red_curve_is_valid = false;
- Geom::Point * b = g_new(Geom::Point, 4*n_points);
- Geom::Point * points = g_new(Geom::Point, 4*n_points);
- for (unsigned int i = 0; i < pc->ps.size(); i++) {
- points[i] = pc->ps[i];
- }
+ int n_points = this->ps.size();
// worst case gives us a segment per point
- int max_segs = 4*n_points;
+ int max_segs = 4 * n_points;
- int const n_segs = Geom::bezier_fit_cubic_r(b, points, n_points,
- tolerance_sq, max_segs);
+ std::vector<Geom::Point> b(max_segs);
- if ( n_segs > 0)
- {
+ int const n_segs = Geom::bezier_fit_cubic_r(b.data(), this->ps.data(), n_points, tolerance_sq, max_segs);
+
+ if (n_segs > 0) {
/* Fit and draw and reset state */
- pc->green_curve->moveto(b[0]);
+ this->green_curve->moveto(b[0]);
+
for (int c = 0; c < n_segs; c++) {
- pc->green_curve->curveto(b[4*c+1], b[4*c+2], b[4*c+3]);
+ this->green_curve->curveto(b[4 * c + 1], b[4 * c + 2], b[4 * c + 3]);
}
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->green_curve);
+
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->green_curve);
/* Fit and draw and copy last point */
- g_assert(!pc->green_curve->is_empty());
+ g_assert(!this->green_curve->is_empty());
/* Set up direction of next curve. */
{
- Geom::Curve const * last_seg = pc->green_curve->last_segment();
+ Geom::Curve const * last_seg = this->green_curve->last_segment();
g_assert( last_seg ); // Relevance: validity of (*last_seg)
- pc->p[0] = last_seg->finalPoint();
- pc->npoints = 1;
+ this->p[0] = last_seg->finalPoint();
+ this->npoints = 1;
Geom::Curve *last_seg_reverse = last_seg->reverse();
Geom::Point const req_vec( -last_seg_reverse->unitTangentAt(0) );
delete last_seg_reverse;
- pc->req_tangent = ( ( Geom::is_zero(req_vec) || !in_svg_plane(req_vec) )
+ this->req_tangent = ( ( Geom::is_zero(req_vec) || !in_svg_plane(req_vec) )
? Geom::Point(0, 0)
: Geom::unit_vector(req_vec) );
}
}
- g_free(b);
- g_free(points);
- pc->ps.clear();
+
+ this->ps.clear();
}
/* interpolates the sketched curve and tweaks the current sketch interpolation*/
-static void
-sketch_interpolate(PencilTool *pc)
-{
- if ( pc->ps.size() <= 1 ) {
+void PencilTool::_sketchInterpolate() {
+ if ( this->ps.size() <= 1 ) {
return;
}
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4;
- double const tolerance_sq = 0.02 * square( pc->desktop->w2d().descrim() *
- tol) * exp(0.2*tol - 2);
+ double const tolerance_sq = 0.02 * square(this->desktop->w2d().descrim() * tol) * exp(0.2 * tol - 2);
bool average_all_sketches = prefs->getBool("/tools/freehand/pencil/average_all_sketches", true);
- g_assert(is_zero(pc->req_tangent)
- || is_unit_vector(pc->req_tangent));
- Geom::Point const tHatEnd(0, 0);
+ g_assert(is_zero(this->req_tangent) || is_unit_vector(this->req_tangent));
- guint n_points = pc->ps.size();
- pc->red_curve->reset();
- pc->red_curve_is_valid = false;
+ this->red_curve->reset();
+ this->red_curve_is_valid = false;
- Geom::Point * b = g_new(Geom::Point, 4*n_points);
- Geom::Point * points = g_new(Geom::Point, 4*n_points);
- for (unsigned i = 0; i < pc->ps.size(); i++) {
- points[i] = pc->ps[i];
- }
+ int n_points = this->ps.size();
// worst case gives us a segment per point
- int max_segs = 4*n_points;
+ int max_segs = 4 * n_points;
- int const n_segs = Geom::bezier_fit_cubic_r(b, points, n_points,
- tolerance_sq, max_segs);
+ std::vector<Geom::Point> b(max_segs);
- if ( n_segs > 0)
- {
+ int const n_segs = Geom::bezier_fit_cubic_r(b.data(), this->ps.data(), n_points, tolerance_sq, max_segs);
+
+ if (n_segs > 0) {
Geom::Path fit(b[0]);
+
for (int c = 0; c < n_segs; c++) {
- fit.appendNew<Geom::CubicBezier>(b[4*c+1], b[4*c+2], b[4*c+3]);
+ fit.appendNew<Geom::CubicBezier>(b[4 * c + 1], b[4 * c + 2], b[4 * c + 3]);
}
+
Geom::Piecewise<Geom::D2<Geom::SBasis> > fit_pwd2 = fit.toPwSb();
- if ( pc->sketch_n > 0 ) {
- double t =0.;
+ if (this->sketch_n > 0) {
+ double t;
+
if (average_all_sketches) {
// Average = (sum of all) / n
// = (sum of all + new one) / n+1
// = ((old average)*n + new one) / n+1
- t = pc->sketch_n / (pc->sketch_n + 1.);
+ t = this->sketch_n / (this->sketch_n + 1.);
} else {
t = 0.5;
}
- pc->sketch_interpolation = Geom::lerp(t, fit_pwd2, pc->sketch_interpolation);
+
+ this->sketch_interpolation = Geom::lerp(t, fit_pwd2, this->sketch_interpolation);
+
// simplify path, to eliminate small segments
- Path *path = new Path;
- path->LoadPathVector(Geom::path_from_piecewise(pc->sketch_interpolation, 0.01));
- path->Simplify(0.5);
- Geom::PathVector *pathv = path->MakePathVector();
- pc->sketch_interpolation = (*pathv)[0].toPwSb();
- delete path;
+ Path path;
+ path.LoadPathVector(Geom::path_from_piecewise(this->sketch_interpolation, 0.01));
+ path.Simplify(0.5);
+
+ Geom::PathVector *pathv = path.MakePathVector();
+ this->sketch_interpolation = (*pathv)[0].toPwSb();
delete pathv;
} else {
- pc->sketch_interpolation = fit_pwd2;
+ this->sketch_interpolation = fit_pwd2;
}
- pc->sketch_n++;
- pc->green_curve->reset();
- pc->green_curve->set_pathvector(Geom::path_from_piecewise(pc->sketch_interpolation, 0.01));
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->green_curve);
+ this->sketch_n++;
+
+ this->green_curve->reset();
+ this->green_curve->set_pathvector(Geom::path_from_piecewise(this->sketch_interpolation, 0.01));
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->green_curve);
/* Fit and draw and copy last point */
- g_assert(!pc->green_curve->is_empty());
+ g_assert(!this->green_curve->is_empty());
/* Set up direction of next curve. */
{
- Geom::Curve const * last_seg = pc->green_curve->last_segment();
+ Geom::Curve const * last_seg = this->green_curve->last_segment();
g_assert( last_seg ); // Relevance: validity of (*last_seg)
- pc->p[0] = last_seg->finalPoint();
- pc->npoints = 1;
+ this->p[0] = last_seg->finalPoint();
+ this->npoints = 1;
Geom::Curve *last_seg_reverse = last_seg->reverse();
Geom::Point const req_vec( -last_seg_reverse->unitTangentAt(0) );
delete last_seg_reverse;
- pc->req_tangent = ( ( Geom::is_zero(req_vec) || !in_svg_plane(req_vec) )
+ this->req_tangent = ( ( Geom::is_zero(req_vec) || !in_svg_plane(req_vec) )
? Geom::Point(0, 0)
: Geom::unit_vector(req_vec) );
}
}
- g_free(b);
- g_free(points);
- pc->ps.clear();
+
+ this->ps.clear();
}
-static void
-fit_and_split(PencilTool *pc)
-{
- g_assert( pc->npoints > 1 );
+void PencilTool::_fitAndSplit() {
+ g_assert( this->npoints > 1 );
double const tolerance_sq = 0;
Geom::Point b[4];
- g_assert(is_zero(pc->req_tangent)
- || is_unit_vector(pc->req_tangent));
+ g_assert(is_zero(this->req_tangent)
+ || is_unit_vector(this->req_tangent));
Geom::Point const tHatEnd(0, 0);
- int const n_segs = Geom::bezier_fit_cubic_full(b, NULL, pc->p, pc->npoints,
- pc->req_tangent, tHatEnd,
+ int const n_segs = Geom::bezier_fit_cubic_full(b, NULL, this->p, this->npoints,
+ this->req_tangent, tHatEnd,
tolerance_sq, 1);
if ( n_segs > 0
- && unsigned(pc->npoints) < G_N_ELEMENTS(pc->p) )
+ && unsigned(this->npoints) < G_N_ELEMENTS(this->p) )
{
/* Fit and draw and reset state */
- pc->red_curve->reset();
- pc->red_curve->moveto(b[0]);
- pc->red_curve->curveto(b[1], b[2], b[3]);
- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve);
- pc->red_curve_is_valid = true;
+ this->red_curve->reset();
+ this->red_curve->moveto(b[0]);
+ this->red_curve->curveto(b[1], b[2], b[3]);
+ sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve);
+ this->red_curve_is_valid = true;
} else {
/* Fit and draw and copy last point */
- g_assert(!pc->red_curve->is_empty());
+ g_assert(!this->red_curve->is_empty());
/* Set up direction of next curve. */
{
- Geom::Curve const * last_seg = pc->red_curve->last_segment();
+ Geom::Curve const * last_seg = this->red_curve->last_segment();
g_assert( last_seg ); // Relevance: validity of (*last_seg)
- pc->p[0] = last_seg->finalPoint();
- pc->npoints = 1;
+ this->p[0] = last_seg->finalPoint();
+ this->npoints = 1;
Geom::Curve *last_seg_reverse = last_seg->reverse();
Geom::Point const req_vec( -last_seg_reverse->unitTangentAt(0) );
delete last_seg_reverse;
- pc->req_tangent = ( ( Geom::is_zero(req_vec) || !in_svg_plane(req_vec) )
+ this->req_tangent = ( ( Geom::is_zero(req_vec) || !in_svg_plane(req_vec) )
? Geom::Point(0, 0)
: Geom::unit_vector(req_vec) );
}
- pc->green_curve->append_continuous(pc->red_curve, 0.0625);
- SPCurve *curve = pc->red_curve->copy();
+ this->green_curve->append_continuous(this->red_curve, 0.0625);
+ SPCurve *curve = this->red_curve->copy();
/// \todo fixme:
- SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(pc->desktop), curve);
+ SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), curve);
curve->unref();
- sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
+ sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), this->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
- pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape);
+ this->green_bpaths = g_slist_prepend(this->green_bpaths, cshape);
- pc->red_curve_is_valid = false;
+ this->red_curve_is_valid = false;
}
}
diff --git a/src/ui/tools/pencil-tool.h b/src/ui/tools/pencil-tool.h
index 6ced9eb56..e8d156dbd 100644
--- a/src/ui/tools/pencil-tool.h
+++ b/src/ui/tools/pencil-tool.h
@@ -7,6 +7,10 @@
#include "ui/tools/freehand-base.h"
+#include <2geom/piecewise.h>
+#include <2geom/d2.h>
+#include <2geom/sbasis.h>
+
#define SP_PENCIL_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::PencilTool*>((ToolBase*)obj))
#define SP_IS_PENCIL_CONTEXT(obj) (dynamic_cast<const Inkscape::UI::Tools::PencilTool*>((const ToolBase*)obj) != NULL)
@@ -48,6 +52,24 @@ public:
protected:
virtual void setup();
virtual bool root_handler(GdkEvent* event);
+
+private:
+ bool _handleButtonPress(GdkEventButton const &bevent);
+ bool _handleMotionNotify(GdkEventMotion const &mevent);
+ bool _handleButtonRelease(GdkEventButton const &revent);
+ bool _handleKeyPress(GdkEventKey const &event);
+ bool _handleKeyRelease(GdkEventKey const &event);
+
+ void _setStartpoint(Geom::Point const &p);
+ void _setEndpoint(Geom::Point const &p);
+ void _finishEndpoint();
+ void _addFreehandPoint(Geom::Point const &p, guint state);
+ void _fitAndSplit();
+ void _interpolate();
+ void _sketchInterpolate();
+
+ void _cancel();
+ void _endpointSnap(Geom::Point &p, guint const state);
};
}
diff --git a/src/ui/tools/rect-tool.cpp b/src/ui/tools/rect-tool.cpp
index 263fdea84..39f422c1a 100644
--- a/src/ui/tools/rect-tool.cpp
+++ b/src/ui/tools/rect-tool.cpp
@@ -66,20 +66,12 @@ const std::string& RectTool::getPrefsPath() {
const std::string RectTool::prefsPath = "/tools/shapes/rect";
-RectTool::RectTool() : ToolBase() {
- this->cursor_shape = cursor_rect_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
- this->xp = 0;
- this->yp = 0;
- this->tolerance = 0;
- this->within_tolerance = false;
- this->item_to_select = NULL;
-
- this->rect = NULL;
-
- this->rx = 0.0;
- this->ry = 0.0;
+RectTool::RectTool()
+ : ToolBase(cursor_rect_xpm, 4, 4)
+ , rect(NULL)
+ , rx(0)
+ , ry(0)
+{
}
void RectTool::finish() {
@@ -243,7 +235,7 @@ bool RectTool::root_handler(GdkEvent* event) {
this->drag(motion_dt, event->motion.state); // this will also handle the snapping
gobble_motion_events(GDK_BUTTON1_MASK);
ret = TRUE;
- } else if (!sp_event_context_knot_mouseover(this)) {
+ } else if (!this->sp_event_context_knot_mouseover()) {
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp
index 498882417..83bef17c9 100644
--- a/src/ui/tools/select-tool.cpp
+++ b/src/ui/tools/select-tool.cpp
@@ -90,24 +90,24 @@ sp_load_handles(int start, int count, char const **xpm) {
}
}
-SelectTool::SelectTool() : ToolBase() {
- this->grabbed = 0;
- this->item = 0;
-
- this->dragging = FALSE;
- this->moved = FALSE;
- this->button_press_shift = false;
- this->button_press_ctrl = false;
- this->button_press_alt = false;
- this->cycling_items = NULL;
- this->cycling_items_cmp = NULL;
- this->cycling_items_selected_before = NULL;
- this->cycling_cur_item = NULL;
- this->cycling_wrap = true;
- this->_seltrans = NULL;
- this->_describer = NULL;
-
-
+SelectTool::SelectTool()
+ // Don't load a default cursor
+ : ToolBase(NULL, 0, 0)
+ , dragging(false)
+ , moved(false)
+ , button_press_shift(false)
+ , button_press_ctrl(false)
+ , button_press_alt(false)
+ , cycling_items(NULL)
+ , cycling_items_cmp(NULL)
+ , cycling_items_selected_before(NULL)
+ , cycling_cur_item(NULL)
+ , cycling_wrap(true)
+ , item(NULL)
+ , grabbed(NULL)
+ , _seltrans(NULL)
+ , _describer(NULL)
+{
// cursors in select context
CursorSelectMouseover = sp_cursor_new_from_xpm(cursor_select_m_xpm , 1, 1);
CursorSelectDragging = sp_cursor_new_from_xpm(cursor_select_d_xpm , 1, 1);
@@ -125,7 +125,6 @@ SelectTool::SelectTool() : ToolBase() {
//static bool within_tolerance = false;
static bool is_cycling = false;
static bool moved_while_cycling = false;
-ToolBase *prev_event_context = NULL;
SelectTool::~SelectTool() {
@@ -441,24 +440,20 @@ void SelectTool::sp_select_context_cycle_through_items(Inkscape::Selection *sele
}
}
+void SelectTool::sp_select_context_reset_opacities() {
+ for (GList *l = this->cycling_items; l != NULL; l = g_list_next(l)) {
+ Inkscape::DrawingItem *arenaitem = SP_ITEM(l->data)->get_arenaitem(this->desktop->dkey);
+ arenaitem->setOpacity(SP_SCALE24_TO_FLOAT(SP_ITEM(l->data)->style->opacity.value));
+ }
-static void
-sp_select_context_reset_opacities(ToolBase *event_context)
-{
- // SPDesktop *desktop = event_context->desktop;
- SelectTool *sc = SP_SELECT_CONTEXT(event_context);
- Inkscape::DrawingItem *arenaitem;
- for (GList *l = sc->cycling_items; l != NULL; l = g_list_next(l)) {
- arenaitem = SP_ITEM(l->data)->get_arenaitem(event_context->desktop->dkey);
- arenaitem->setOpacity(SP_SCALE24_TO_FLOAT(SP_ITEM(l->data)->style->opacity.value));
- }
- g_list_free(sc->cycling_items);
- g_list_free(sc->cycling_items_selected_before);
- g_list_free(sc->cycling_items_cmp);
- sc->cycling_items = NULL;
- sc->cycling_items_selected_before = NULL;
- sc->cycling_cur_item = NULL;
- sc->cycling_items_cmp = NULL;
+ g_list_free(this->cycling_items);
+ g_list_free(this->cycling_items_selected_before);
+ g_list_free(this->cycling_items_cmp);
+
+ this->cycling_items = NULL;
+ this->cycling_items_selected_before = NULL;
+ this->cycling_cur_item = NULL;
+ this->cycling_items_cmp = NULL;
}
bool SelectTool::root_handler(GdkEvent* event) {
@@ -545,11 +540,9 @@ bool SelectTool::root_handler(GdkEvent* event) {
case GDK_MOTION_NOTIFY:
{
- if (is_cycling)
- {
- moved_while_cycling = true;
- prev_event_context = this;
- }
+ if (is_cycling) {
+ moved_while_cycling = true;
+ }
tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
@@ -811,14 +804,12 @@ bool SelectTool::root_handler(GdkEvent* event) {
GdkEventScroll *scroll_event = (GdkEventScroll*) event;
if (scroll_event->state & GDK_MOD1_MASK) { // alt modified pressed
- if (moved_while_cycling)
- {
- moved_while_cycling = false;
- sp_select_context_reset_opacities(prev_event_context);
- prev_event_context = NULL;
- }
+ if (moved_while_cycling) {
+ moved_while_cycling = false;
+ this->sp_select_context_reset_opacities();
+ }
- is_cycling = true;
+ is_cycling = true;
bool shift_pressed = scroll_event->state & GDK_SHIFT_MASK;
@@ -1205,18 +1196,15 @@ bool SelectTool::root_handler(GdkEvent* event) {
Inkscape::Rubberband::get(desktop)->setMode(RUBBERBAND_MODE_RECT);
}
} else {
- if (alt) { // TODO: Should we have a variable like is_cycling or is it harmless to run this piece of code each time?
+ if (alt) {
// quit cycle-selection and reset opacities
- if (is_cycling)
- {
- sp_select_context_reset_opacities(this);
- is_cycling = false;
- }
-
+ if (is_cycling) {
+ this->sp_select_context_reset_opacities();
+ is_cycling = false;
+ }
}
}
- }
// set cursor to default.
if (!desktop->isWaitingCursor()) {
// Do we need to reset the cursor here on key release ?
@@ -1224,7 +1212,7 @@ bool SelectTool::root_handler(GdkEvent* event) {
//gdk_window_set_cursor(window, event_context->cursor);
}
break;
-
+ }
default:
break;
}
diff --git a/src/ui/tools/select-tool.h b/src/ui/tools/select-tool.h
index b26fc03bc..edc4069a2 100644
--- a/src/ui/tools/select-tool.h
+++ b/src/ui/tools/select-tool.h
@@ -35,8 +35,8 @@ public:
SelectTool();
virtual ~SelectTool();
- guint dragging : 1;
- guint moved : 1;
+ bool dragging;
+ bool moved;
bool button_press_shift;
bool button_press_ctrl;
bool button_press_alt;
@@ -64,6 +64,7 @@ public:
private:
bool sp_select_context_abort();
void sp_select_context_cycle_through_items(Inkscape::Selection *selection, GdkEventScroll *scroll_event, bool shift_pressed);
+ void sp_select_context_reset_opacities();
};
}
diff --git a/src/ui/tools/spiral-tool.cpp b/src/ui/tools/spiral-tool.cpp
index 005b2d239..5ae229df8 100644
--- a/src/ui/tools/spiral-tool.cpp
+++ b/src/ui/tools/spiral-tool.cpp
@@ -65,21 +65,13 @@ const std::string& SpiralTool::getPrefsPath() {
const std::string SpiralTool::prefsPath = "/tools/shapes/spiral";
-SpiralTool::SpiralTool() : ToolBase() {
- this->cursor_shape = cursor_spiral_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
- this->xp = 0;
- this->yp = 0;
- this->tolerance = 0;
- this->within_tolerance = false;
- this->item_to_select = NULL;
-
- this->spiral = NULL;
-
- this->revo = 3.0;
- this->exp = 1.0;
- this->t0 = 0.0;
+SpiralTool::SpiralTool()
+ : ToolBase(cursor_spiral_xpm, 4, 4)
+ , spiral(NULL)
+ , revo(3)
+ , exp(1)
+ , t0(0)
+{
}
void SpiralTool::finish() {
@@ -217,7 +209,7 @@ bool SpiralTool::root_handler(GdkEvent* event) {
gobble_motion_events(GDK_BUTTON1_MASK);
ret = TRUE;
- } else if (!sp_event_context_knot_mouseover(this)) {
+ } else if (!this->sp_event_context_knot_mouseover()) {
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
Geom::Point const motion_w(event->motion.x, event->motion.y);
diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp
index 0ded1e44b..08d3119a1 100644
--- a/src/ui/tools/spray-tool.cpp
+++ b/src/ui/tools/spray-tool.cpp
@@ -79,6 +79,11 @@ using namespace std;
#define DDC_RED_RGBA 0xff0000ff
#define DYNA_MIN_WIDTH 1.0e-6
+// Disabled in 0.91 because of Bug #1274831 (crash, spraying an object
+// with the mode: spray object in single path)
+// Please enable again when working on 1.0
+#define ENABLE_SPRAY_MODE_SINGLE_PATH
+
#include "tool-factory.h"
namespace Inkscape {
@@ -86,15 +91,15 @@ namespace UI {
namespace Tools {
namespace {
- ToolBase* createSprayContext() {
- return new SprayTool();
- }
+ ToolBase* createSprayContext() {
+ return new SprayTool();
+ }
- bool sprayContextRegistered = ToolFactory::instance().registerObject("/tools/spray", createSprayContext);
+ bool sprayContextRegistered = ToolFactory::instance().registerObject("/tools/spray", createSprayContext);
}
const std::string& SprayTool::getPrefsPath() {
- return SprayTool::prefsPath;
+ return SprayTool::prefsPath;
}
const std::string SprayTool::prefsPath = "/tools/spray";
@@ -114,9 +119,9 @@ inline double NormalDistribution(double mu, double sigma)
static void sp_spray_rotate_rel(Geom::Point c, SPDesktop */*desktop*/, SPItem *item, Geom::Rotate const &rotation)
{
Geom::Translate const s(c);
- Geom::Affine affine = Geom::Affine(s).inverse() * Geom::Affine(rotation) * Geom::Affine(s);
+ Geom::Affine affine = s.inverse() * rotation * s;
// Rotate item.
- item->set_i2d_affine(item->i2dt_affine() * (Geom::Affine)affine);
+ item->set_i2d_affine(item->i2dt_affine() * affine);
// Use each item's own transform writer, consistent with sp_selection_apply_affine()
item->doWriteTransform(item->getRepr(), item->transform);
// Restore the center position (it's changed because the bbox center changed)
@@ -134,35 +139,30 @@ static void sp_spray_scale_rel(Geom::Point c, SPDesktop */*desktop*/, SPItem *it
item->doWriteTransform(item->getRepr(), item->transform);
}
-SprayTool::SprayTool() : ToolBase() {
- this->usetilt = 0;
- this->dilate_area = 0;
- this->usetext = false;
- this->population = 0;
- this->is_drawing = false;
- this->mode = 0;
- this->usepressure = 0;
-
- this->cursor_shape = cursor_spray_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
-
- /* attributes */
- this->dragging = FALSE;
- this->distrib = 1;
- this->width = 0.2;
- this->force = 0.2;
- this->ratio = 0;
- this->tilt = 0;
- this->mean = 0.2;
- this->rotation_variation = 0;
- this->standard_deviation = 0.2;
- this->scale = 1;
- this->scale_variation = 1;
- this->pressure = TC_DEFAULT_PRESSURE;
-
- this->is_dilating = false;
- this->has_dilated = false;
+SprayTool::SprayTool()
+ : ToolBase(cursor_spray_xpm, 4, 4, false)
+ , pressure(TC_DEFAULT_PRESSURE)
+ , dragging(false)
+ , usepressure(0)
+ , usetilt(0)
+ , usetext(false)
+ , width(0.2)
+ , ratio(0)
+ , tilt(0)
+ , rotation_variation(0)
+ , force(0.2)
+ , population(0)
+ , scale_variation(1)
+ , scale(1)
+ , mean(0.2)
+ , standard_deviation(0.2)
+ , distrib(1)
+ , mode(0)
+ , is_drawing(false)
+ , is_dilating(false)
+ , has_dilated(false)
+ , dilate_area(NULL)
+{
}
SprayTool::~SprayTool() {
@@ -194,22 +194,22 @@ void SprayTool::update_cursor(bool /*with_shift*/) {
sel_message = g_strdup_printf("%s", _("<b>Nothing</b> selected"));
}
- switch (this->mode) {
- case SPRAY_MODE_COPY:
- this->message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag, click or click and scroll to spray <b>copies</b> of the initial selection."), sel_message);
- break;
- case SPRAY_MODE_CLONE:
- this->message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag, click or click and scroll to spray <b>clones</b> of the initial selection."), sel_message);
- break;
- case SPRAY_MODE_SINGLE_PATH:
- this->message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag, click or click and scroll to spray in a <b>single path</b> of the initial selection."), sel_message);
- break;
- default:
- break;
- }
-
- this->sp_event_context_update_cursor();
- g_free(sel_message);
+ switch (this->mode) {
+ case SPRAY_MODE_COPY:
+ this->message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag, click or click and scroll to spray <b>copies</b> of the initial selection."), sel_message);
+ break;
+ case SPRAY_MODE_CLONE:
+ this->message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag, click or click and scroll to spray <b>clones</b> of the initial selection."), sel_message);
+ break;
+ case SPRAY_MODE_SINGLE_PATH:
+ this->message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag, click or click and scroll to spray in a <b>single path</b> of the initial selection."), sel_message);
+ break;
+ default:
+ break;
+ }
+
+ this->sp_event_context_update_cursor();
+ g_free(sel_message);
}
void SprayTool::setup() {
@@ -404,7 +404,7 @@ static bool sp_spray_recursive(SPDesktop *desktop,
SPItem *item_copied;
if(_fid <= population)
{
- // duplicate
+ // Duplicate
SPDocument *doc = item->document;
Inkscape::XML::Document* xml_doc = doc->getReprDoc();
Inkscape::XML::Node *old_repr = item->getRepr();
@@ -413,24 +413,24 @@ static bool sp_spray_recursive(SPDesktop *desktop,
parent->appendChild(copy);
SPObject *new_obj = doc->getObjectByRepr(copy);
- item_copied = SP_ITEM(new_obj); //convertion object->item
+ item_copied = SP_ITEM(new_obj); // Convertion object->item
Geom::Point center=item->getCenter();
sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale,_scale));
sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale,scale));
sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle));
- //Move the cursor p
+ // Move the cursor p
Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
did = true;
}
}
+#ifdef ENABLE_SPRAY_MODE_SINGLE_PATH
} else if (mode == SPRAY_MODE_SINGLE_PATH) {
- SPItem *father = NULL; //initial Object
- SPItem *item_copied = NULL; //Projected Object
- SPItem *unionResult = NULL; //previous union
- SPItem *son = NULL; //father copy
+ SPItem *parent_item = NULL; // Initial object
+ SPItem *item_copied = NULL; // Projected object
+ SPItem *unionResult = NULL; // Previous union
int i=1;
for (GSList *items = g_slist_copy(const_cast<GSList *>(selection->itemList()));
@@ -439,55 +439,49 @@ static bool sp_spray_recursive(SPDesktop *desktop,
SPItem *item1 = SP_ITEM(items->data);
if (i == 1) {
- father = item1;
+ parent_item = item1;
}
if (i == 2) {
unionResult = item1;
}
i++;
}
- SPDocument *doc = father->document;
+ SPDocument *doc = parent_item->document;
Inkscape::XML::Document* xml_doc = doc->getReprDoc();
- Inkscape::XML::Node *old_repr = father->getRepr();
+ Inkscape::XML::Node *old_repr = parent_item->getRepr();
Inkscape::XML::Node *parent = old_repr->parent();
- Geom::OptRect a = father->documentVisualBounds();
+ Geom::OptRect a = parent_item->documentVisualBounds();
if (a) {
- if (i == 2) {
- Inkscape::XML::Node *copy1 = old_repr->duplicate(xml_doc);
- parent->appendChild(copy1);
- SPObject *new_obj1 = doc->getObjectByRepr(copy1);
- son = SP_ITEM(new_obj1); // conversion object->item
- unionResult = son;
- Inkscape::GC::release(copy1);
- }
-
if (_fid <= population) { // Rules the population of objects sprayed
- // duplicates the father
- Inkscape::XML::Node *copy2 = old_repr->duplicate(xml_doc);
- parent->appendChild(copy2);
- SPObject *new_obj2 = doc->getObjectByRepr(copy2);
- item_copied = SP_ITEM(new_obj2);
+ // Duplicates the parent item
+ Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc);
+ parent->appendChild(copy);
+ SPObject *new_obj = doc->getObjectByRepr(copy);
+ item_copied = SP_ITEM(new_obj);
// Move around the cursor
Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
- Geom::Point center=father->getCenter();
+ Geom::Point center = parent_item->getCenter();
sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(_scale, _scale));
sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(scale, scale));
sp_spray_rotate_rel(center, desktop, item_copied, Geom::Rotate(angle));
sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
- // union and duplication
+ // Union and duplication
selection->clear();
selection->add(item_copied);
- selection->add(unionResult);
+ if (unionResult) { // No need to add the very first item (initialized with NULL).
+ selection->add(unionResult);
+ }
sp_selected_path_union_skip_undo(selection, selection->desktop());
- selection->add(father);
- Inkscape::GC::release(copy2);
+ selection->add(parent_item);
+ Inkscape::GC::release(copy);
did = true;
}
}
+#endif
} else if (mode == SPRAY_MODE_CLONE) {
Geom::OptRect a = item->documentVisualBounds();
if (a) {
@@ -500,15 +494,15 @@ static bool sp_spray_recursive(SPDesktop *desktop,
// Creation of the clone
Inkscape::XML::Node *clone = xml_doc->createElement("svg:use");
- // Ad the clone to the list of the father's sons
+ // Ad the clone to the list of the parent's children
parent->appendChild(clone);
- // Generates the link between father and son attributes
+ // Generates the link between parent and child attributes
gchar *href_str = g_strdup_printf("#%s", old_repr->attribute("id"));
clone->setAttribute("xlink:href", href_str, false);
g_free(href_str);
SPObject *clone_object = doc->getObjectByRepr(clone);
- // conversion object->item
+ // Conversion object->item
item_copied = SP_ITEM(clone_object);
Geom::Point center = item->getCenter();
sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(_scale, _scale));
@@ -529,8 +523,8 @@ static bool sp_spray_recursive(SPDesktop *desktop,
static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point p, Geom::Point vector, bool reverse)
{
- Inkscape::Selection *selection = sp_desktop_selection(SP_EVENT_CONTEXT(tc)->desktop);
- SPDesktop *desktop = SP_EVENT_CONTEXT(tc)->desktop;
+ SPDesktop *desktop = tc->desktop;
+ Inkscape::Selection *selection = sp_desktop_selection(desktop);
if (selection->isEmpty()) {
return false;
@@ -554,18 +548,35 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point
double move_mean = get_move_mean(tc);
double move_standard_deviation = get_move_standard_deviation(tc);
- for (GSList *items = g_slist_copy(const_cast<GSList *>(selection->itemList()));
- items != NULL;
- items = items->next) {
+ {
+ GSList *const original_selection = g_slist_copy(const_cast<GSList *>(selection->itemList()));
- SPItem *item = SP_ITEM(items->data);
+ for (GSList *items = original_selection;
+ items != NULL;
+ items = items->next) {
+ sp_object_ref(SP_ITEM(items->data));
+ }
- if (is_transform_modes(tc->mode)) {
- if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, move_force, tc->population, tc->scale, tc->scale_variation, reverse, move_mean, move_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib))
- did = true;
- } else {
- if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, path_force, tc->population, tc->scale, tc->scale_variation, reverse, path_mean, path_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib))
- did = true;
+ for (GSList *items = original_selection;
+ items != NULL;
+ items = items->next) {
+ SPItem *item = SP_ITEM(items->data);
+
+ if (is_transform_modes(tc->mode)) {
+ if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, move_force, tc->population, tc->scale, tc->scale_variation, reverse, move_mean, move_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib)) {
+ did = true;
+ }
+ } else {
+ if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, path_force, tc->population, tc->scale, tc->scale_variation, reverse, path_mean, path_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib)) {
+ did = true;
+ }
+ }
+ }
+
+ for (GSList *items = original_selection;
+ items != NULL;
+ items = items->next) {
+ sp_object_unref(SP_ITEM(items->data));
}
}
@@ -582,9 +593,9 @@ static void sp_spray_update_area(SprayTool *tc)
static void sp_spray_switch_mode(SprayTool *tc, gint mode, bool with_shift)
{
- // select the button mode
+ // Select the button mode
SP_EVENT_CONTEXT(tc)->desktop->setToolboxSelectOneValue("spray_tool_mode", mode);
- // need to set explicitly, because the prefs may not have changed by the previous
+ // Need to set explicitly, because the prefs may not have changed by the previous
tc->mode = mode;
tc->update_cursor(with_shift);
}
@@ -631,7 +642,7 @@ bool SprayTool::root_handler(GdkEvent* event) {
Geom::Point motion_doc(desktop->dt2doc(motion_dt));
sp_spray_extinput(this, event);
- // draw the dilating cursor
+ // Draw the dilating cursor
double radius = get_dilate_radius(this);
Geom::Affine const sm (Geom::Scale(radius/(1-this->ratio), radius/(1+this->ratio)) );
sp_canvas_item_affine_absolute(this->dilate_area, (sm*Geom::Rotate(this->tilt))*Geom::Translate(desktop->w2d(motion_w)));
@@ -645,19 +656,19 @@ bool SprayTool::root_handler(GdkEvent* event) {
this->message_context->flash(Inkscape::ERROR_MESSAGE, _("<b>Nothing selected!</b> Select objects to spray."));
}
- // dilating:
+ // Dilating:
if (this->is_drawing && ( event->motion.state & GDK_BUTTON1_MASK )) {
sp_spray_dilate(this, motion_w, motion_doc, motion_doc - this->last_push, event->button.state & GDK_SHIFT_MASK? true : false);
//this->last_push = motion_doc;
this->has_dilated = true;
- // it's slow, so prevent clogging up with events
+ // It's slow, so prevent clogging up with events
gobble_motion_events(GDK_BUTTON1_MASK);
return TRUE;
}
}
break;
- /*Spray with the scroll*/
+ /* Spray with the scroll */
case GDK_SCROLL: {
if (event->scroll.state & GDK_BUTTON1_MASK) {
double temp ;
@@ -708,7 +719,7 @@ bool SprayTool::root_handler(GdkEvent* event) {
if (this->is_dilating && event->button.button == 1 && !this->space_panning) {
if (!this->has_dilated) {
- // if we did not rub, do a light tap
+ // If we did not rub, do a light tap
this->pressure = 0.03;
sp_spray_dilate(this, motion_w, desktop->dt2doc(motion_dt), Geom::Point(0,0), MOD__SHIFT(event));
}
@@ -748,6 +759,7 @@ bool SprayTool::root_handler(GdkEvent* event) {
ret = TRUE;
}
break;
+#ifdef ENABLE_SPRAY_MODE_SINGLE_PATH
case GDK_KEY_l:
case GDK_KEY_L:
if (MOD__SHIFT_ONLY(event)) {
@@ -755,6 +767,7 @@ bool SprayTool::root_handler(GdkEvent* event) {
ret = TRUE;
}
break;
+#endif
case GDK_KEY_Up:
case GDK_KEY_KP_Up:
if (!MOD__CTRL_ONLY(event)) {
@@ -784,7 +797,7 @@ bool SprayTool::root_handler(GdkEvent* event) {
if (this->width > 1.0) {
this->width = 1.0;
}
- // the same spinbutton is for alt+x
+ // The same spinbutton is for alt+x
desktop->setToolboxAdjustmentValue("altx-spray", this->width * 100);
sp_spray_update_area(this);
ret = TRUE;
@@ -867,7 +880,7 @@ bool SprayTool::root_handler(GdkEvent* event) {
// if ((SP_EVENT_CONTEXT_CLASS(sp_spray_context_parent_class))->root_handler) {
// ret = (SP_EVENT_CONTEXT_CLASS(sp_spray_context_parent_class))->root_handler(event_context, event);
// }
- ret = ToolBase::root_handler(event);
+ ret = ToolBase::root_handler(event);
}
return ret;
diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h
index e7362fd50..1a8f98006 100644
--- a/src/ui/tools/spray-tool.h
+++ b/src/ui/tools/spray-tool.h
@@ -61,10 +61,10 @@ public:
gdouble pressure;
/* attributes */
- guint dragging : 1; /* mouse state: mouse is dragging */
- guint usepressure : 1;
- guint usetilt : 1;
- bool usetext ;
+ bool dragging; /* mouse state: mouse is dragging */
+ bool usepressure;
+ bool usetilt;
+ bool usetext;
double width;
double ratio;
diff --git a/src/ui/tools/star-tool.cpp b/src/ui/tools/star-tool.cpp
index b5d8c4418..68f998920 100644
--- a/src/ui/tools/star-tool.cpp
+++ b/src/ui/tools/star-tool.cpp
@@ -69,25 +69,15 @@ const std::string& StarTool::getPrefsPath() {
const std::string StarTool::prefsPath = "/tools/shapes/star";
-StarTool::StarTool() : ToolBase() {
- this->randomized = 0;
- this->rounded = 0;
-
- this->cursor_shape = cursor_star_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
- this->xp = 0;
- this->yp = 0;
- this->tolerance = 0;
- this->within_tolerance = false;
- this->item_to_select = NULL;
- //this->tool_url = "/tools/shapes/star";
-
- this->star = NULL;
-
- this->magnitude = 5;
- this->proportion = 0.5;
- this->isflatsided = false;
+StarTool::StarTool()
+ : ToolBase(cursor_star_xpm, 4, 4)
+ , star(NULL)
+ , magnitude(5)
+ , proportion(0.5)
+ , isflatsided(false)
+ , rounded(0)
+ , randomized(0)
+{
}
void StarTool::finish() {
@@ -228,7 +218,7 @@ bool StarTool::root_handler(GdkEvent* event) {
gobble_motion_events(GDK_BUTTON1_MASK);
ret = TRUE;
- } else if (!sp_event_context_knot_mouseover(this)) {
+ } else if (!this->sp_event_context_knot_mouseover()) {
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp
index 2927606a7..ac830fe6b 100644
--- a/src/ui/tools/text-tool.cpp
+++ b/src/ui/tools/text-tool.cpp
@@ -61,11 +61,6 @@ namespace Inkscape {
namespace UI {
namespace Tools {
-static void sp_text_context_selection_changed(Inkscape::Selection *selection, TextTool *tc);
-static void sp_text_context_selection_modified(Inkscape::Selection *selection, guint flags, TextTool *tc);
-static bool sp_text_context_style_set(SPCSSAttr const *css, TextTool *tc);
-static int sp_text_context_style_query(SPStyle *style, int property, TextTool *tc);
-
static void sp_text_context_validate_cursor_iterators(TextTool *tc);
static void sp_text_context_update_cursor(TextTool *tc, bool scroll_to_see = true);
static void sp_text_context_update_text_selection(TextTool *tc);
@@ -77,51 +72,40 @@ static gint sptc_focus_out(GtkWidget *widget, GdkEventFocus *event, TextTool *tc
static void sptc_commit(GtkIMContext *imc, gchar *string, TextTool *tc);
namespace {
- ToolBase* createTextContext() {
- return new TextTool();
- }
+ ToolBase* createTextContext() {
+ return new TextTool();
+ }
- bool textContextRegistered = ToolFactory::instance().registerObject("/tools/text", createTextContext);
+ bool textContextRegistered = ToolFactory::instance().registerObject("/tools/text", createTextContext);
}
const std::string& TextTool::getPrefsPath() {
- return TextTool::prefsPath;
+ return TextTool::prefsPath;
}
const std::string TextTool::prefsPath = "/tools/text";
-TextTool::TextTool() : ToolBase() {
- this->preedit_string = 0;
- this->unipos = 0;
-
- this->cursor_shape = cursor_text_xpm;
- this->hot_x = 7;
- this->hot_y = 7;
-
- this->xp = 0;
- this->yp = 0;
- this->tolerance = 0;
- this->within_tolerance = false;
-
- this->imc = NULL;
-
- this->text = NULL;
- this->pdoc = Geom::Point(0, 0);
-
- this->unimode = false;
-
- this->cursor = NULL;
- this->indicator = NULL;
- this->frame = NULL;
- this->grabbed = NULL;
- this->timeout = 0;
- this->show = FALSE;
- this->phase = 0;
- this->nascent_object = 0;
- this->over_text = 0;
- this->dragging = 0;
- this->creating = 0;
+TextTool::TextTool()
+ : ToolBase(cursor_text_xpm, 7, 7)
+ , imc(NULL)
+ , text(NULL)
+ , pdoc(0, 0)
+ , unimode(false)
+ , unipos(0)
+ , cursor(NULL)
+ , indicator(NULL)
+ , frame(NULL)
+ , timeout(0)
+ , show(false)
+ , phase(false)
+ , nascent_object(false)
+ , over_text(false)
+ , dragging(0)
+ , creating(false)
+ , grabbed(NULL)
+ , preedit_string(NULL)
+{
}
TextTool::~TextTool() {
@@ -154,6 +138,7 @@ void TextTool::setup() {
this->indicator = sp_canvas_item_new(sp_desktop_controls(desktop), SP_TYPE_CTRLRECT, NULL);
SP_CTRLRECT(this->indicator)->setRectangle(Geom::Rect(Geom::Point(0, 0), Geom::Point(100, 100)));
SP_CTRLRECT(this->indicator)->setColor(0x0000ff7f, false, 0);
+ SP_CTRLRECT(this->indicator)->setShadow(1, 0xffffff7f);
sp_canvas_item_hide(this->indicator);
this->frame = sp_canvas_item_new(sp_desktop_controls(desktop), SP_TYPE_CTRLRECT, NULL);
@@ -175,7 +160,7 @@ void TextTool::setup() {
*/
gtk_im_context_set_use_preedit(this->imc, FALSE);
gtk_im_context_set_client_window(this->imc,
- gtk_widget_get_window (canvas));
+ gtk_widget_get_window (canvas));
g_signal_connect(G_OBJECT(canvas), "focus_in_event", G_CALLBACK(sptc_focus_in), this);
g_signal_connect(G_OBJECT(canvas), "focus_out_event", G_CALLBACK(sptc_focus_out), this);
@@ -195,20 +180,20 @@ void TextTool::setup() {
this->shape_editor->set_item(item, SH_KNOTHOLDER);
}
- this->sel_changed_connection = sp_desktop_selection(desktop)->connectChanged(
- sigc::bind(sigc::ptr_fun(&sp_text_context_selection_changed), this)
- );
- this->sel_modified_connection = sp_desktop_selection(desktop)->connectModified(
- sigc::bind(sigc::ptr_fun(&sp_text_context_selection_modified), this)
- );
+ this->sel_changed_connection = sp_desktop_selection(desktop)->connectChangedFirst(
+ sigc::mem_fun(*this, &TextTool::_selectionChanged)
+ );
+ this->sel_modified_connection = sp_desktop_selection(desktop)->connectModifiedFirst(
+ sigc::mem_fun(*this, &TextTool::_selectionModified)
+ );
this->style_set_connection = desktop->connectSetStyle(
- sigc::bind(sigc::ptr_fun(&sp_text_context_style_set), this)
- );
+ sigc::mem_fun(*this, &TextTool::_styleSet)
+ );
this->style_query_connection = desktop->connectQueryStyle(
- sigc::bind(sigc::ptr_fun(&sp_text_context_style_query), this)
- );
+ sigc::mem_fun(*this, &TextTool::_styleQueried)
+ );
- sp_text_context_selection_changed(sp_desktop_selection(desktop), this);
+ _selectionChanged(sp_desktop_selection(desktop));
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (prefs->getBool("/tools/text/selcue")) {
@@ -265,6 +250,8 @@ void TextTool::finish() {
}
this->text_selection_quads.clear();
+
+ ToolBase::finish();
}
bool TextTool::item_handler(SPItem* item, GdkEvent* event) {
@@ -404,7 +391,7 @@ bool TextTool::item_handler(SPItem* item, GdkEvent* event) {
}
if (!ret) {
- ret = ToolBase::item_handler(item, event);
+ ret = ToolBase::item_handler(item, event);
}
return ret;
@@ -445,7 +432,7 @@ static void sp_text_context_setup_text(TextTool *tc)
text_item->updateRepr();
text_item->doWriteTransform(text_item->getRepr(), text_item->transform, NULL, true);
DocumentUndo::done(sp_desktop_document(ec->desktop), SP_VERB_CONTEXT_TEXT,
- _("Create text"));
+ _("Create text"));
}
/**
@@ -485,7 +472,7 @@ static void insert_uni_char(TextTool *const tc)
sp_text_context_update_cursor(tc);
sp_text_context_update_text_selection(tc);
DocumentUndo::done(sp_desktop_document(tc->desktop), SP_VERB_DIALOG_TRANSFORM,
- _("Insert Unicode character"));
+ _("Insert Unicode character"));
}
}
@@ -610,7 +597,7 @@ bool TextTool::root_handler(GdkEvent* event) {
g_string_free(xs, FALSE);
g_string_free(ys, FALSE);
- } else if (!sp_event_context_knot_mouseover(this)) {
+ } else if (!this->sp_event_context_knot_mouseover()) {
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
@@ -675,8 +662,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_desktop_apply_style_tool(desktop, ft->getRepr(), "/tools/text", true);
sp_desktop_selection(desktop)->set(ft);
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Flowed text is created."));
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("Create flowed text"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Create flowed text"));
} else {
desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("The frame is <b>too small</b> for the current font size. Flowed text not created."));
}
@@ -815,8 +801,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("No-break space"));
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("Insert no-break space"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Insert no-break space"));
return TRUE;
}
break;
@@ -852,8 +837,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_repr_css_set_property(css, "font-weight", "normal");
sp_te_apply_style(this->text, this->text_sel_start, this->text_sel_end, css);
sp_repr_css_attr_unref(css);
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("Make bold"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Make bold"));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
return TRUE;
@@ -870,8 +854,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_repr_css_set_property(css, "font-style", "italic");
sp_te_apply_style(this->text, this->text_sel_start, this->text_sel_end, css);
sp_repr_css_attr_unref(css);
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("Make italic"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Make italic"));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
return TRUE;
@@ -909,8 +892,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("New line"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("New line"));
return TRUE;
}
case GDK_KEY_BackSpace:
@@ -951,8 +933,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("Backspace"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Backspace"));
}
return TRUE;
case GDK_KEY_Delete:
@@ -990,8 +971,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("Delete"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Delete"));
}
return TRUE;
case GDK_KEY_Left:
@@ -1007,8 +987,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(mul*-1, 0));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:left", SP_VERB_CONTEXT_TEXT,
- _("Kern to the left"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:left", SP_VERB_CONTEXT_TEXT, _("Kern to the left"));
} else {
if (MOD__CTRL(event))
this->text_sel_end.cursorLeftWithControl();
@@ -1032,8 +1011,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(mul*1, 0));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:right", SP_VERB_CONTEXT_TEXT,
- _("Kern to the right"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:right", SP_VERB_CONTEXT_TEXT, _("Kern to the right"));
} else {
if (MOD__CTRL(event))
this->text_sel_end.cursorRightWithControl();
@@ -1057,8 +1035,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(0, mul*-1));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:up", SP_VERB_CONTEXT_TEXT,
- _("Kern up"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:up", SP_VERB_CONTEXT_TEXT, _("Kern up"));
} else {
if (MOD__CTRL(event))
this->text_sel_end.cursorUpWithControl();
@@ -1082,8 +1059,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(0, mul*1));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:down", SP_VERB_CONTEXT_TEXT,
- _("Kern down"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:down", SP_VERB_CONTEXT_TEXT, _("Kern down"));
} else {
if (MOD__CTRL(event))
this->text_sel_end.cursorDownWithControl();
@@ -1158,8 +1134,7 @@ bool TextTool::root_handler(GdkEvent* event) {
} else {
sp_te_adjust_rotation(this->text, this->text_sel_start, this->text_sel_end, desktop, -90);
}
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "textrot:ccw", SP_VERB_CONTEXT_TEXT,
- _("Rotate counterclockwise"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "textrot:ccw", SP_VERB_CONTEXT_TEXT, _("Rotate counterclockwise"));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
return TRUE;
@@ -1179,8 +1154,7 @@ bool TextTool::root_handler(GdkEvent* event) {
} else {
sp_te_adjust_rotation(this->text, this->text_sel_start, this->text_sel_end, desktop, 90);
}
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "textrot:cw", SP_VERB_CONTEXT_TEXT,
- _("Rotate clockwise"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "textrot:cw", SP_VERB_CONTEXT_TEXT, _("Rotate clockwise"));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
return TRUE;
@@ -1196,15 +1170,13 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -10);
else
sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -1);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "linespacing:dec", SP_VERB_CONTEXT_TEXT,
- _("Contract line spacing"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "linespacing:dec", SP_VERB_CONTEXT_TEXT, _("Contract line spacing"));
} else {
if (MOD__SHIFT(event))
sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -10);
else
sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -1);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "letterspacing:dec", SP_VERB_CONTEXT_TEXT,
- _("Contract letter spacing"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "letterspacing:dec", SP_VERB_CONTEXT_TEXT, _("Contract letter spacing"));
}
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
@@ -1221,15 +1193,13 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 10);
else
sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 1);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "linespacing:inc", SP_VERB_CONTEXT_TEXT,
- _("Expand line spacing"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "linespacing:inc", SP_VERB_CONTEXT_TEXT, _("Expand line spacing"));
} else {
if (MOD__SHIFT(event))
sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 10);
else
sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 1);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "letterspacing:inc", SP_VERB_CONTEXT_TEXT,
- _("Expand letter spacing"));\
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "letterspacing:inc", SP_VERB_CONTEXT_TEXT, _("Expand letter spacing"));\
}
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
@@ -1313,32 +1283,32 @@ bool sp_text_paste_inline(ToolBase *ec)
Glib::ustring const clip_text = refClipboard->wait_for_text();
if (!clip_text.empty()) {
- // Fix for 244940
- // The XML standard defines the following as valid characters
- // (Extensible Markup Language (XML) 1.0 (Fourth Edition) paragraph 2.2)
- // char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
- // Since what comes in off the paste buffer will go right into XML, clean
- // the text here.
- Glib::ustring text(clip_text);
- Glib::ustring::iterator itr = text.begin();
- gunichar paste_string_uchar;
-
- while(itr != text.end())
- {
- paste_string_uchar = *itr;
-
- // Make sure we don't have a control character. We should really check
- // for the whole range above... Add the rest of the invalid cases from
- // above if we find additional issues
- if(paste_string_uchar >= 0x00000020 ||
- paste_string_uchar == 0x00000009 ||
- paste_string_uchar == 0x0000000A ||
- paste_string_uchar == 0x0000000D) {
- itr++;
- } else {
- itr = text.erase(itr);
- }
- }
+ // Fix for 244940
+ // The XML standard defines the following as valid characters
+ // (Extensible Markup Language (XML) 1.0 (Fourth Edition) paragraph 2.2)
+ // char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
+ // Since what comes in off the paste buffer will go right into XML, clean
+ // the text here.
+ Glib::ustring text(clip_text);
+ Glib::ustring::iterator itr = text.begin();
+ gunichar paste_string_uchar;
+
+ while(itr != text.end())
+ {
+ paste_string_uchar = *itr;
+
+ // Make sure we don't have a control character. We should really check
+ // for the whole range above... Add the rest of the invalid cases from
+ // above if we find additional issues
+ if(paste_string_uchar >= 0x00000020 ||
+ paste_string_uchar == 0x00000009 ||
+ paste_string_uchar == 0x0000000A ||
+ paste_string_uchar == 0x0000000D) {
+ ++itr;
+ } else {
+ itr = text.erase(itr);
+ }
+ }
if (!tc->text) { // create text if none (i.e. if nascent_object)
sp_text_context_setup_text(tc);
@@ -1359,7 +1329,7 @@ bool sp_text_paste_inline(ToolBase *ec)
begin = end + 1;
}
DocumentUndo::done(sp_desktop_document(ec->desktop), SP_VERB_CONTEXT_TEXT,
- _("Paste text"));
+ _("Paste text"));
return true;
}
@@ -1435,12 +1405,11 @@ bool sp_text_delete_selection(ToolBase *ec)
/**
* \param selection Should not be NULL.
*/
-static void
-sp_text_context_selection_changed(Inkscape::Selection *selection, TextTool *tc)
+void TextTool::_selectionChanged(Inkscape::Selection *selection)
{
g_assert(selection != NULL);
- ToolBase *ec = SP_EVENT_CONTEXT(tc);
+ ToolBase *ec = SP_EVENT_CONTEXT(this);
ec->shape_editor->unset_item(SH_KNOTHOLDER);
SPItem *item = selection->singleItem();
@@ -1448,70 +1417,68 @@ sp_text_context_selection_changed(Inkscape::Selection *selection, TextTool *tc)
ec->shape_editor->set_item(item, SH_KNOTHOLDER);
}
- if (tc->text && (item != tc->text)) {
- sp_text_context_forget_text(tc);
+ if (this->text && (item != this->text)) {
+ sp_text_context_forget_text(this);
}
- tc->text = NULL;
+ this->text = NULL;
if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) {
- tc->text = item;
- Inkscape::Text::Layout const *layout = te_get_layout(tc->text);
+ this->text = item;
+ Inkscape::Text::Layout const *layout = te_get_layout(this->text);
if (layout)
- tc->text_sel_start = tc->text_sel_end = layout->end();
+ this->text_sel_start = this->text_sel_end = layout->end();
} else {
- tc->text = NULL;
+ this->text = NULL;
}
// we update cursor without scrolling, because this position may not be final;
// item_handler moves cusros to the point of click immediately
- sp_text_context_update_cursor(tc, false);
- sp_text_context_update_text_selection(tc);
+ sp_text_context_update_cursor(this, false);
+ sp_text_context_update_text_selection(this);
}
-static void
-sp_text_context_selection_modified(Inkscape::Selection */*selection*/, guint /*flags*/, TextTool *tc)
+void TextTool::_selectionModified(Inkscape::Selection */*selection*/, guint /*flags*/)
{
- sp_text_context_update_cursor(tc);
- sp_text_context_update_text_selection(tc);
+ sp_text_context_update_cursor(this);
+ sp_text_context_update_text_selection(this);
}
-static bool sp_text_context_style_set(SPCSSAttr const *css, TextTool *tc)
+bool TextTool::_styleSet(SPCSSAttr const *css)
{
- if (tc->text == NULL)
+ if (this->text == NULL)
return false;
- if (tc->text_sel_start == tc->text_sel_end)
+ if (this->text_sel_start == this->text_sel_end)
return false; // will get picked up by the parent and applied to the whole text object
- sp_te_apply_style(tc->text, tc->text_sel_start, tc->text_sel_end, css);
- DocumentUndo::done(sp_desktop_document(tc->desktop), SP_VERB_CONTEXT_TEXT,
- _("Set text style"));
- sp_text_context_update_cursor(tc);
- sp_text_context_update_text_selection(tc);
+ sp_te_apply_style(this->text, this->text_sel_start, this->text_sel_end, css);
+ DocumentUndo::done(sp_desktop_document(this->desktop), SP_VERB_CONTEXT_TEXT,
+ _("Set text style"));
+ sp_text_context_update_cursor(this);
+ sp_text_context_update_text_selection(this);
return true;
}
-static int
-sp_text_context_style_query(SPStyle *style, int property, TextTool *tc)
+int TextTool::_styleQueried(SPStyle *style, int property)
{
- if (tc->text == NULL) {
+ if (this->text == NULL) {
return QUERY_STYLE_NOTHING;
}
- const Inkscape::Text::Layout *layout = te_get_layout(tc->text);
+ const Inkscape::Text::Layout *layout = te_get_layout(this->text);
if (layout == NULL) {
return QUERY_STYLE_NOTHING;
}
- sp_text_context_validate_cursor_iterators(tc);
+ sp_text_context_validate_cursor_iterators(this);
GSList *styles_list = NULL;
Inkscape::Text::Layout::iterator begin_it, end_it;
- if (tc->text_sel_start < tc->text_sel_end) {
- begin_it = tc->text_sel_start;
- end_it = tc->text_sel_end;
+ if (this->text_sel_start < this->text_sel_end) {
+ begin_it = this->text_sel_start;
+ end_it = this->text_sel_end;
} else {
- begin_it = tc->text_sel_end;
- end_it = tc->text_sel_start;
+ begin_it = this->text_sel_end;
+ end_it = this->text_sel_start;
}
if (begin_it == end_it) {
if (!begin_it.prevCharacter()) {
@@ -1636,7 +1603,7 @@ static void sp_text_context_update_text_selection(TextTool *tc)
// the selection update (can't do both atomically, alas)
if (!tc->desktop) return;
- for (std::vector<SPCanvasItem*>::iterator it = tc->text_selection_quads.begin() ; it != tc->text_selection_quads.end() ; it++) {
+ for (std::vector<SPCanvasItem*>::iterator it = tc->text_selection_quads.begin() ; it != tc->text_selection_quads.end() ; ++it) {
sp_canvas_item_hide(*it);
sp_canvas_item_destroy(*it);
}
@@ -1725,7 +1692,7 @@ static void sptc_commit(GtkIMContext */*imc*/, gchar *string, TextTool *tc)
sp_text_context_update_text_selection(tc);
DocumentUndo::done(tc->text->document, SP_VERB_CONTEXT_TEXT,
- _("Type text"));
+ _("Type text"));
}
void sp_text_context_place_cursor (TextTool *tc, SPObject *text, Inkscape::Text::Layout::iterator where)
diff --git a/src/ui/tools/text-tool.h b/src/ui/tools/text-tool.h
index ef8a67984..ca2b3d19a 100644
--- a/src/ui/tools/text-tool.h
+++ b/src/ui/tools/text-tool.h
@@ -61,15 +61,15 @@ public:
SPCanvasItem *frame; // hiliting the first frame of flowtext; FIXME: make this a list to accommodate arbitrarily many chained shapes
std::vector<SPCanvasItem*> text_selection_quads;
gint timeout;
- guint show : 1;
- guint phase : 1;
- guint nascent_object : 1; // true if we're clicked on canvas to put cursor, but no text typed yet so ->text is still NULL
+ bool show;
+ bool phase;
+ bool nascent_object; // true if we're clicked on canvas to put cursor, but no text typed yet so ->text is still NULL
- guint over_text : 1; // true if cursor is over a text object
+ bool over_text; // true if cursor is over a text object
guint dragging : 2; // dragging selection over text
- guint creating : 1; // dragging rubberband to create flowtext
+ bool creating; // dragging rubberband to create flowtext
SPCanvasItem *grabbed; // we grab while we are creating, to get events even if the mouse goes out of the window
Geom::Point p0; // initial point if the flowtext rect
@@ -84,6 +84,12 @@ public:
virtual bool item_handler(SPItem* item, GdkEvent* event);
virtual const std::string& getPrefsPath();
+
+private:
+ void _selectionChanged(Inkscape::Selection *selection);
+ void _selectionModified(Inkscape::Selection *selection, guint flags);
+ bool _styleSet(SPCSSAttr const *css);
+ int _styleQueried(SPStyle *style, int property);
};
bool sp_text_paste_inline(ToolBase *ec);
diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp
index 6c7867633..4195c9eb2 100644
--- a/src/ui/tools/tool-base.cpp
+++ b/src/ui/tools/tool-base.cpp
@@ -57,6 +57,7 @@
#include "shape-editor.h"
#include "sp-guide.h"
#include "color.h"
+#include "knot.h"
// globals for temporary switching to selector by space
static bool selector_toggled = FALSE;
@@ -90,28 +91,27 @@ SPDesktop const& ToolBase::getDesktop() const {
return *desktop;
}
-ToolBase::ToolBase() {
- this->hot_y = 0;
- this->xp = 0;
- this->cursor_shape = 0;
- this->pref_observer = 0;
- this->hot_x = 0;
- this->yp = 0;
- this->within_tolerance = false;
- this->tolerance = 0;
- //this->key = 0;
- this->item_to_select = 0;
-
- this->desktop = NULL;
- this->cursor = NULL;
- this->message_context = NULL;
- this->_selcue = NULL;
- this->_grdrag = NULL;
- this->space_panning = false;
- this->shape_editor = NULL;
- this->_delayed_snap_event = NULL;
- this->_dse_callback_in_process = false;
- //this->tool_url = NULL;
+ToolBase::ToolBase(gchar const *const *cursor_shape, gint hot_x, gint hot_y, bool uses_snap)
+ : pref_observer(NULL)
+ , cursor(NULL)
+ , xp(0)
+ , yp(0)
+ , tolerance(0)
+ , within_tolerance(false)
+ , item_to_select(NULL)
+ , message_context(NULL)
+ , _selcue(NULL)
+ , _grdrag(NULL)
+ , shape_editor(NULL)
+ , space_panning(false)
+ , _delayed_snap_event(NULL)
+ , _dse_callback_in_process(false)
+ , desktop(NULL)
+ , _uses_snap(uses_snap)
+ , cursor_shape(cursor_shape)
+ , hot_x(hot_x)
+ , hot_y(hot_y)
+{
}
ToolBase::~ToolBase() {
@@ -145,9 +145,9 @@ ToolBase::~ToolBase() {
/**
* Set the cursor to a standard GDK cursor
*/
-static void sp_event_context_set_cursor(ToolBase *event_context, GdkCursorType cursor_type) {
+void ToolBase::sp_event_context_set_cursor(GdkCursorType cursor_type) {
- GtkWidget *w = GTK_WIDGET(sp_desktop_canvas(event_context->desktop));
+ GtkWidget *w = GTK_WIDGET(sp_desktop_canvas(this->desktop));
GdkDisplay *display = gdk_display_get_default();
GdkCursor *cursor = gdk_cursor_new_for_display(display, cursor_type);
@@ -386,7 +386,9 @@ bool ToolBase::root_handler(GdkEvent* event) {
case 1:
if (this->space_panning) {
// When starting panning, make sure there are no snap events pending because these might disable the panning again
- sp_event_context_discard_delayed_snap_event(this);
+ if (_uses_snap) {
+ sp_event_context_discard_delayed_snap_event(this);
+ }
panning = 1;
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
@@ -404,7 +406,9 @@ bool ToolBase::root_handler(GdkEvent* event) {
zoom_rb = 2;
} else {
// When starting panning, make sure there are no snap events pending because these might disable the panning again
- sp_event_context_discard_delayed_snap_event(this);
+ if (_uses_snap) {
+ sp_event_context_discard_delayed_snap_event(this);
+ }
panning = 2;
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
@@ -420,7 +424,9 @@ bool ToolBase::root_handler(GdkEvent* event) {
case 3:
if ((event->button.state & GDK_SHIFT_MASK) || (event->button.state & GDK_CONTROL_MASK)) {
// When starting panning, make sure there are no snap events pending because these might disable the panning again
- sp_event_context_discard_delayed_snap_event(this);
+ if (_uses_snap) {
+ sp_event_context_discard_delayed_snap_event(this);
+ }
panning = 3;
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
@@ -482,7 +488,7 @@ bool ToolBase::root_handler(GdkEvent* event) {
if (panning_cursor == 0) {
panning_cursor = 1;
- sp_event_context_set_cursor(this, GDK_FLEUR);
+ this->sp_event_context_set_cursor(GDK_FLEUR);
}
Geom::Point const motion_w(event->motion.x, event->motion.y);
@@ -741,10 +747,12 @@ bool ToolBase::root_handler(GdkEvent* event) {
if (within_tolerance == true) {
// Space was pressed, but not panned
sp_toggle_selector(desktop);
- ret = TRUE;
+
+ // Be careful, sp_toggle_selector will delete ourselves.
+ // Thus, make sure we return immediately.
+ return true;
}
- within_tolerance = false;
break;
case GDK_KEY_Q:
@@ -876,10 +884,9 @@ bool ToolBase::item_handler(SPItem* item, GdkEvent* event) {
/**
* Returns true if we're hovering above a knot (needed because we don't want to pre-snap in that case).
*/
-bool sp_event_context_knot_mouseover(ToolBase *ec)
-{
- if (ec->shape_editor) {
- return ec->shape_editor->knot_mouseover();
+bool ToolBase::sp_event_context_knot_mouseover() const {
+ if (this->shape_editor) {
+ return this->shape_editor->knot_mouseover();
}
return false;
@@ -947,6 +954,10 @@ void sp_event_context_read(ToolBase *ec, gchar const *key) {
gint sp_event_context_root_handler(ToolBase * event_context,
GdkEvent * event)
{
+ if (!event_context->_uses_snap) {
+ return sp_event_context_virtual_root_handler(event_context, event);
+ }
+
switch (event->type) {
case GDK_MOTION_NOTIFY:
sp_event_context_snap_delay_handler(event_context, NULL, NULL,
@@ -977,13 +988,18 @@ gint sp_event_context_root_handler(ToolBase * event_context,
gint sp_event_context_virtual_root_handler(ToolBase * event_context, GdkEvent * event) {
gint ret = false;
- if (event_context) { // If no event-context is available then do nothing, otherwise Inkscape would crash
- // (see the comment in SPDesktop::set_event_context, and bug LP #622350)
- //ret = (SP_EVENT_CONTEXT_CLASS(G_OBJECT_GET_CLASS(event_context)))->root_handler(event_context, event);
- ret = event_context->root_handler(event);
- set_event_location(event_context->desktop, event);
+ if (event_context) {
+ // The root handler also handles pressing the space key.
+ // This will toggle the current tool and delete the current one.
+ // Thus, save a pointer to the desktop before calling it.
+ SPDesktop* desktop = event_context->desktop;
+
+ ret = event_context->root_handler(event);
+
+ set_event_location(desktop, event);
}
+
return ret;
}
@@ -991,7 +1007,12 @@ gint sp_event_context_virtual_root_handler(ToolBase * event_context, GdkEvent *
* Calls virtual item_handler(), the item event handling function.
*/
gint sp_event_context_item_handler(ToolBase * event_context,
- SPItem * item, GdkEvent * event) {
+ SPItem * item, GdkEvent * event)
+{
+ if (!event_context->_uses_snap) {
+ return sp_event_context_virtual_item_handler(event_context, item, event);
+ }
+
switch (event->type) {
case GDK_MOTION_NOTIFY:
sp_event_context_snap_delay_handler(event_context, (gpointer) item, NULL, (GdkEventMotion *) event, DelayedSnapEvent::EVENTCONTEXT_ITEM_HANDLER);
@@ -1111,7 +1132,7 @@ void sp_event_show_modifier_tip(Inkscape::MessageContext *message_context,
* Use this instead of simply event->keyval, so that your keyboard shortcuts
* work regardless of layouts (e.g., in Cyrillic).
*/
-guint get_group0_keyval(GdkEventKey *event) {
+guint get_group0_keyval(GdkEventKey const *event) {
guint keyval = 0;
gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display(
@@ -1228,7 +1249,7 @@ void sp_event_context_snap_delay_handler(ToolBase *ec,
static guint32 prev_time;
static boost::optional<Geom::Point> prev_pos;
- if (ec->_dse_callback_in_process) {
+ if (!ec->_uses_snap || ec->_dse_callback_in_process) {
return;
}
diff --git a/src/ui/tools/tool-base.h b/src/ui/tools/tool-base.h
index 7ed5875b1..b27de9030 100644
--- a/src/ui/tools/tool-base.h
+++ b/src/ui/tools/tool-base.h
@@ -12,24 +12,29 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#include <glib-object.h>
+#include <stddef.h>
+#include <string>
+
+#include <2geom/point.h>
#include <gdk/gdk.h>
+#include <glib-object.h>
+#include <sigc++/trackable.h>
#include "knot.h"
-#include "2geom/forward.h"
#include "preferences.h"
-class GrDrag;
-class SPDesktop;
-class SPItem;
-class ShapeEditor;
+namespace Glib {
+ class ustring;
+}
+
+class GrDrag;
+class SPDesktop;
+class SPItem;
+class ShapeEditor;
namespace Inkscape {
class MessageContext;
class SelCue;
- namespace XML {
- class Node;
- }
}
#define SP_EVENT_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::ToolBase*>((Inkscape::UI::Tools::ToolBase*)obj))
@@ -44,8 +49,7 @@ class ToolBase;
gboolean sp_event_context_snap_watchdog_callback(gpointer data);
void sp_event_context_discard_delayed_snap_event(ToolBase *ec);
-class DelayedSnapEvent
-{
+class DelayedSnapEvent {
public:
enum DelayedSnapEventOrigin {
UNDEFINED_HANDLER = 0,
@@ -59,12 +63,19 @@ public:
};
DelayedSnapEvent(ToolBase *event_context, gpointer const dse_item, gpointer dse_item2, GdkEventMotion const *event, DelayedSnapEvent::DelayedSnapEventOrigin const origin)
- : _timer_id(0), _event(NULL), _item(dse_item), _item2(dse_item2), _origin(origin), _event_context(event_context)
+ : _timer_id(0)
+ , _event(NULL)
+ , _item(dse_item)
+ , _item2(dse_item2)
+ , _origin(origin)
+ , _event_context(event_context)
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
double value = prefs->getDoubleLimited("/options/snapdelay/value", 0, 0, 1000);
+
_timer_id = g_timeout_add(value, &sp_event_context_snap_watchdog_callback, this);
_event = gdk_event_copy((GdkEvent*) event);
+
((GdkEventMotion *)_event)->time = GDK_CURRENT_TIME;
}
@@ -73,11 +84,25 @@ public:
if (_event != NULL) gdk_event_free(_event); // Remove the copy of the original event
}
- ToolBase* getEventContext() {return _event_context;}
- DelayedSnapEventOrigin getOrigin() {return _origin;}
- GdkEvent* getEvent() {return _event;}
- gpointer getItem() {return _item;}
- gpointer getItem2() {return _item2;}
+ ToolBase* getEventContext() {
+ return _event_context;
+ }
+
+ DelayedSnapEventOrigin getOrigin() {
+ return _origin;
+ }
+
+ GdkEvent* getEvent() {
+ return _event;
+ }
+
+ gpointer getItem() {
+ return _item;
+ }
+
+ gpointer getItem2() {
+ return _item2;
+ }
private:
guint _timer_id;
@@ -104,13 +129,16 @@ void sp_event_context_snap_delay_handler(ToolBase *ec, gpointer const dse_item,
* plus few abstract base classes. Writing a new tool involves
* subclassing ToolBase.
*/
-class ToolBase {
+class ToolBase
+ : public sigc::trackable
+{
public:
void enableSelectionCue (bool enable=true);
void enableGrDrag (bool enable=true);
bool deleteSelectedDrag(bool just_one);
- ToolBase();
+ ToolBase(gchar const *const *cursor_shape, gint hot_x, gint hot_y, bool uses_snap = true);
+
virtual ~ToolBase();
Inkscape::Preferences::Observer *pref_observer;
@@ -118,6 +146,7 @@ public:
gint xp, yp; ///< where drag started
gint tolerance;
+
bool within_tolerance; ///< are we still within tolerance of origin
SPItem *item_to_select; ///< the item where mouse_press occurred, to
@@ -132,7 +161,10 @@ public:
Inkscape::SelCue *_selcue;
GrDrag *_grdrag;
- GrDrag *get_drag () {return _grdrag;}
+
+ GrDrag *get_drag () {
+ return _grdrag;
+ }
ShapeEditor* shape_editor;
@@ -157,8 +189,10 @@ public:
*/
class ToolPrefObserver: public Inkscape::Preferences::Observer {
public:
- ToolPrefObserver(Glib::ustring const &path, ToolBase *ec) :
- Inkscape::Preferences::Observer(path), ec(ec) {
+ ToolPrefObserver(Glib::ustring const &path, ToolBase *ec)
+ : Inkscape::Preferences::Observer(path)
+ , ec(ec)
+ {
}
virtual void notify(Inkscape::Preferences::Entry const &val) {
@@ -176,14 +210,23 @@ public:
void sp_event_context_update_cursor();
SPDesktop *desktop;
+ bool _uses_snap; // TODO: make protected or private
protected:
+ /// An xpm containing the shape of the tool's cursor.
gchar const *const *cursor_shape;
- gint hot_x, hot_y; ///< indicates the cursor's hot spot
+
+ /// The cursor's hot spot
+ gint hot_x, hot_y;
+
+ bool sp_event_context_knot_mouseover() const;
private:
ToolBase(const ToolBase&);
ToolBase& operator=(const ToolBase&);
+
+ void sp_event_context_set_cursor(GdkCursorType cursor_type);
+
};
void sp_event_context_read(ToolBase *ec, gchar const *key);
@@ -201,7 +244,7 @@ gint gobble_motion_events(gint mask);
void sp_event_show_modifier_tip(Inkscape::MessageContext *message_context, GdkEvent *event,
gchar const *ctrl_tip, gchar const *shift_tip, gchar const *alt_tip);
-guint get_group0_keyval(GdkEventKey *event);
+guint get_group0_keyval(GdkEventKey const *event);
SPItem *sp_event_context_find_item (SPDesktop *desktop, Geom::Point const &p, bool select_under, bool into_groups);
SPItem *sp_event_context_over_item (SPDesktop *desktop, SPItem *item, Geom::Point const &p);
@@ -210,9 +253,9 @@ void sp_toggle_dropper(SPDesktop *dt);
bool sp_event_context_knot_mouseover(ToolBase *ec);
-}
-}
-}
+} // namespace Tools
+} // namespace UI
+} // namespace Inkscape
#endif // SEEN_SP_EVENT_CONTEXT_H
diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp
index 0791eff5a..75650d3af 100644
--- a/src/ui/tools/tweak-tool.cpp
+++ b/src/ui/tools/tweak-tool.cpp
@@ -111,32 +111,25 @@ const std::string& TweakTool::getPrefsPath() {
const std::string TweakTool::prefsPath = "/tools/tweak";
-TweakTool::TweakTool() : ToolBase() {
- this->mode = 0;
- this->dilate_area = 0;
- this->usetilt = 0;
- this->usepressure = 0;
- this->is_drawing = false;
- this->fidelity = 0;
-
- this->cursor_shape = cursor_push_xpm;
- this->hot_x = 4;
- this->hot_y = 4;
-
- /* attributes */
- this->dragging = FALSE;
-
- this->width = 0.2;
- this->force = 0.2;
- this->pressure = TC_DEFAULT_PRESSURE;
-
- this->is_dilating = false;
- this->has_dilated = false;
-
- this->do_h = true;
- this->do_s = true;
- this->do_l = true;
- this->do_o = false;
+TweakTool::TweakTool()
+ : ToolBase(cursor_push_xpm, 4, 4)
+ , pressure(TC_DEFAULT_PRESSURE)
+ , dragging(false)
+ , usepressure(false)
+ , usetilt(false)
+ , width(0.2)
+ , force(0.2)
+ , fidelity(0)
+ , mode(0)
+ , is_drawing(false)
+ , is_dilating(false)
+ , has_dilated(false)
+ , dilate_area(NULL)
+ , do_h(true)
+ , do_s(true)
+ , do_l(true)
+ , do_o(false)
+{
}
TweakTool::~TweakTool() {
diff --git a/src/ui/tools/tweak-tool.h b/src/ui/tools/tweak-tool.h
index 6cbb9aded..7fe4b1856 100644
--- a/src/ui/tools/tweak-tool.h
+++ b/src/ui/tools/tweak-tool.h
@@ -50,9 +50,9 @@ public:
gdouble pressure;
/* attributes */
- guint dragging : 1; /* mouse state: mouse is dragging */
- guint usepressure : 1;
- guint usetilt : 1;
+ bool dragging; /* mouse state: mouse is dragging */
+ bool usepressure;
+ bool usetilt;
double width;
double force;
diff --git a/src/ui/tools/zoom-tool.cpp b/src/ui/tools/zoom-tool.cpp
index d4ede1053..9f99cfe2e 100644
--- a/src/ui/tools/zoom-tool.cpp
+++ b/src/ui/tools/zoom-tool.cpp
@@ -45,12 +45,11 @@ const std::string& ZoomTool::getPrefsPath() {
const std::string ZoomTool::prefsPath = "/tools/zoom";
-ZoomTool::ZoomTool() : ToolBase() {
- this->grabbed = 0;
- this->cursor_shape = cursor_zoom_xpm;
- this->hot_x = 6;
- this->hot_y = 6;
- this->escaped = false;
+ZoomTool::ZoomTool()
+ : ToolBase(cursor_zoom_xpm, 6, 6)
+ , grabbed(NULL)
+ , escaped(false)
+{
}
ZoomTool::~ZoomTool() {
@@ -63,6 +62,8 @@ void ZoomTool::finish() {
sp_canvas_item_ungrab(this->grabbed, GDK_CURRENT_TIME);
this->grabbed = NULL;
}
+
+ ToolBase::finish();
}
void ZoomTool::setup() {