index 6925960ea7eccb4e06dc9e8e8f3e727981e1a012..f6f59fe6b375d5fdab3247be36dec9573905f69d 100644 (file)
#include "inkscape.h"
#include "color.h"
#include "splivarot.h"
+#include "sp-item-group.h"
#include "sp-shape.h"
#include "sp-path.h"
#include "sp-text.h"
ddc->keep_selected = true;
ddc->hatch_spacing = 0;
+ ddc->hatch_spacing_step = 0;
new (&ddc->hatch_pointer_past) std::list<double>();
new (&ddc->hatch_nearest_past) std::list<double>();
ddc->hatch_last_nearest = NR::Point(0,0);
ddc->trace_bg = false;
ddc->is_dilating = false;
+ ddc->has_dilated = false;
}
static void
double
get_dilate_force (SPDynaDrawContext *dc)
{
- return 8 * dc->pressure/SP_EVENT_CONTEXT(dc)->desktop->current_zoom();
+ double force = 4 * dc->pressure/SP_EVENT_CONTEXT(dc)->desktop->current_zoom();
+ if (force > 3) {
+ force += 8 * (force - 3);
+ }
+ return force;
}
bool
-sp_ddc_dilate (SPDynaDrawContext *dc, NR::Point p, bool expand)
+sp_ddc_dilate_recursive (SPItem *item, NR::Point p, bool expand, double radius, double offset)
{
- Inkscape::Selection *selection = sp_desktop_selection(SP_EVENT_CONTEXT(dc)->desktop);
-
- if (selection->isEmpty()) {
- return false;
- }
-
bool did = false;
- double radius = get_dilate_radius(dc);
- double offset = get_dilate_force(dc);
- for (GSList *items = g_slist_copy((GSList *) selection->itemList());
- items != NULL;
- items = items->next) {
-
- SPItem *item = (SPItem *) items->data;
+ if (SP_IS_GROUP(item)) {
+ for (SPObject *child = sp_object_first_child(SP_OBJECT(item)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
+ if (SP_IS_ITEM(child)) {
+ if (sp_ddc_dilate_recursive (SP_ITEM(child), p, expand, radius, offset))
+ did = true;
+ }
+ }
- // only paths
- if (!SP_IS_PATH(item))
- continue;
+ } else if (SP_IS_PATH(item)) {
SPCurve *curve = NULL;
curve = sp_shape_get_curve(SP_SHAPE(item));
if (curve == NULL)
- continue;
+ return false;
// skip those paths whose bboxes are entirely out of reach with our radius
NR::Maybe<NR::Rect> bbox = item->getBounds(sp_item_i2doc_affine(item));
if (bbox) {
bbox->growBy(radius);
if (!bbox->contains(p)) {
- continue;
+ return false;
}
}
Path *orig = Path_for_item(item, false);
if (orig == NULL) {
sp_curve_unref(curve);
- continue;
+ return false;
}
Path *res = new Path;
res->SetBackData(false);
return did;
}
+
+bool
+sp_ddc_dilate (SPDynaDrawContext *dc, NR::Point p, bool expand)
+{
+ Inkscape::Selection *selection = sp_desktop_selection(SP_EVENT_CONTEXT(dc)->desktop);
+
+ if (selection->isEmpty()) {
+ return false;
+ }
+
+ bool did = false;
+ double radius = get_dilate_radius(dc);
+ double offset = get_dilate_force(dc);
+ if (radius == 0 || offset == 0) {
+ return false;
+ }
+
+ for (GSList *items = g_slist_copy((GSList *) selection->itemList());
+ items != NULL;
+ items = items->next) {
+
+ SPItem *item = (SPItem *) items->data;
+
+ if (sp_ddc_dilate_recursive (item, p, expand, radius, offset))
+ did = true;
+
+ }
+
+ return did;
+}
+
void
sp_ddc_update_cursors (SPDynaDrawContext *dc)
{
ret = TRUE;
+ sp_canvas_force_full_redraw_after_interruptions(desktop->canvas, 3);
dc->is_drawing = true;
+ if (event->button.state & GDK_MOD1_MASK) {
+ dc->is_dilating = true;
+ dc->has_dilated = false;
+ }
}
break;
case GDK_MOTION_NOTIFY:
NR::Point const motion_w(event->motion.x,
event->motion.y);
NR::Point motion_dt(desktop->w2d(motion_w));
+ sp_dyna_draw_extinput(dc, event);
// draw the dilating cursor
if (event->motion.state & GDK_MOD1_MASK) {
} else {
dc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
event->motion.state & GDK_SHIFT_MASK?
- _("<b>Thickening %d</b> selected paths; without <b>Shift</b> to thin") :
- _("<b>Thinning %d</b> selected paths; with <b>Shift</b> to thicken"), num);
+ _("<b>Thickening %d</b> selected objects; without <b>Shift</b> to thin") :
+ _("<b>Thinning %d</b> selected objects; with <b>Shift</b> to thicken"), num);
}
} else {
// dilating:
if (dc->is_drawing && ( event->motion.state & GDK_BUTTON1_MASK ) && event->motion.state & GDK_MOD1_MASK) {
sp_ddc_dilate (dc, desktop->dt2doc(motion_dt), event->motion.state & GDK_SHIFT_MASK? true : false);
- dc->is_dilating = true;
+ dc->has_dilated = true;
// it's slow, so prevent clogging up with events
gobble_motion_events(GDK_BUTTON1_MASK);
return TRUE;
dc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Drawing</b> a calligraphic stroke"));
}
- sp_dyna_draw_extinput(dc, event);
if (!sp_dyna_draw_apply(dc, motion_dt)) {
ret = TRUE;
break;
case GDK_BUTTON_RELEASE:
+ {
+ NR::Point const motion_w(event->button.x, event->button.y);
+ NR::Point const motion_dt(desktop->w2d(motion_w));
+
sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time);
+ sp_canvas_end_forced_full_redraws(desktop->canvas);
dc->is_drawing = false;
if ( dc->is_dilating && event->button.button == 1 ) {
+ if (!dc->has_dilated) {
+ // if we did not rub, do a light tap
+ dc->pressure = 0.03;
+ sp_ddc_dilate (dc, desktop->dt2doc(motion_dt), event->button.state & GDK_SHIFT_MASK? true : false);
+ }
dc->is_dilating = false;
+ dc->has_dilated = false;
sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(dc)->desktop),
SP_VERB_CONTEXT_CALLIGRAPHIC,
(event->button.state & GDK_SHIFT_MASK ? _("Thicken paths") : _("Thin paths")));
ret = TRUE;
+
} else if ( dc->dragging && event->button.button == 1 ) {
dc->dragging = FALSE;
- NR::Point const motion_w(event->button.x, event->button.y);
- NR::Point const motion_dt(desktop->w2d(motion_w));
sp_dyna_draw_apply(dc, motion_dt);
/* Remove all temporary line segments */
dc->hatch_item = NULL;
dc->hatch_livarot_path = NULL;
+ if (dc->hatch_spacing != 0 && !dc->keep_selected) {
+ // we do not select the newly drawn path, so increase spacing by step
+ if (dc->hatch_spacing_step == 0) {
+ dc->hatch_spacing_step = dc->hatch_spacing;
+ }
+ dc->hatch_spacing += dc->hatch_spacing_step;
+ }
+
dc->_message_context->clear();
ret = TRUE;
}
break;
+ }
case GDK_KEY_PRESS:
switch (get_group0_keyval (&event->key)) {
case GDK_Control_R:
dc->_message_context->clear();
dc->hatch_spacing = 0;
+ dc->hatch_spacing_step = 0;
break;
case GDK_Alt_L:
case GDK_Alt_R:
} else {
if (dc->keep_selected) {
sp_desktop_selection(desktop)->set(dc->repr);
- } else {
- sp_desktop_selection(desktop)->clear();
- }
+ }
}
} else {