8
8
* Lauris Kaplinski <lauris@kaplinski.com>
9
9
* bulia byak <buliabyak@users.sf.net>
11
* Copyright (C) 2006 Johan Engelen <johan@shouraizou.nl>
12
* Copyright (C) 2002 Mitsuru Oka
11
13
* Copyright (C) 2000-2002 Lauris Kaplinski
12
14
* Copyright (C) 2000-2001 Ximian, Inc.
13
* Copyright (C) 2002 Mitsuru Oka
15
16
* Released under GNU GPL, read the file 'COPYING' for more information
257
259
switch (event->type) {
258
260
case GDK_BUTTON_PRESS:
259
if (event->button.button == 1) {
261
if (event->button.button == 1 && !event_context->space_panning) {
262
264
ac->center = Inkscape::setup_for_drag_start(desktop, event_context, event);
264
SnapManager const &m = desktop->namedview->snap_manager;
265
ac->center = m.freeSnap(Inkscape::Snapper::SNAP_POINT, ac->center, ac->item).getPoint();
266
SnapManager const &m = desktop->namedview->snap_manager;
267
ac->center = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, ac->center, ac->item).getPoint();
266
269
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
267
270
GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
268
271
GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK,
284
287
event_context->within_tolerance = false;
286
289
NR::Point const motion_w(event->motion.x, event->motion.y);
287
NR::Point const motion_dt(desktop->w2d(motion_w));
290
NR::Point motion_dt(desktop->w2d(motion_w));
292
SnapManager const &m = desktop->namedview->snap_manager;
293
motion_dt = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, motion_dt, ac->item).getPoint();
288
295
sp_arc_drag(ac, motion_dt, event->motion.state);
297
gobble_motion_events(GDK_BUTTON1_MASK);
292
302
case GDK_BUTTON_RELEASE:
293
303
event_context->xp = event_context->yp = 0;
294
if (event->button.button == 1) {
304
if (event->button.button == 1 && !event_context->space_panning) {
295
305
dragging = false;
296
306
if (!event_context->within_tolerance) {
297
307
// we've been dragging, finish the arc
324
334
case GDK_Shift_R:
325
335
case GDK_Meta_L: // Meta is when you press Shift+Alt (at least on my machine)
327
sp_event_show_modifier_tip(event_context->defaultMessageContext(), event,
328
_("<b>Ctrl</b>: make circle or integer-ratio ellipse, snap arc/segment angle"),
329
_("<b>Shift</b>: draw around the starting point"),
338
sp_event_show_modifier_tip(event_context->defaultMessageContext(), event,
339
_("<b>Ctrl</b>: make circle or integer-ratio ellipse, snap arc/segment angle"),
340
_("<b>Shift</b>: draw around the starting point"),
401
429
Inkscape::GC::release(repr);
402
430
ac->item->transform = SP_ITEM(desktop->currentRoot())->getRelativeTransform(desktop->currentLayer());
403
431
ac->item->updateRepr();
406
NR::Rect const r = Inkscape::snap_rectangular_box(desktop, ac->item, pt, ac->center, state);
433
sp_canvas_force_full_redraw_after_interruptions(desktop->canvas, 5);
436
bool ctrl_save = false;
437
if ((state & GDK_MOD1_MASK) && (state & GDK_CONTROL_MASK) && !(state & GDK_SHIFT_MASK)) {
438
// if Alt is pressed without Shift in addition to Control, temporarily drop the CONTROL mask
439
// so that the ellipse is not constrained to integer ratios
441
state = state ^ GDK_CONTROL_MASK;
443
NR::Rect r = Inkscape::snap_rectangular_box(desktop, ac->item, pt, ac->center, state);
445
state = state ^ GDK_CONTROL_MASK;
448
NR::Point dir = r.dimensions() / 2;
449
if (state & GDK_MOD1_MASK) {
450
/* With Alt let the ellipse pass through the mouse pointer */
451
NR::Point c = r.midpoint();
453
if (fabs(dir[NR::X]) > 1E-6 && fabs(dir[NR::Y]) > 1E-6) {
454
NR::Matrix const i2d (sp_item_i2d_affine (ac->item));
455
NR::Point new_dir = pt * i2d - c;
456
new_dir[NR::X] *= dir[NR::Y] / dir[NR::X];
457
double lambda = NR::L2(new_dir) / dir[NR::Y];
458
r = NR::Rect (c - lambda*dir, c + lambda*dir);
461
/* with Alt+Ctrl (without Shift) we generate a perfect circle
462
with diameter click point <--> mouse pointer */
463
double l = NR::L2 (dir);
464
NR::Point d = NR::Point (l, l);
465
r = NR::Rect (c - d, c + d);
408
469
sp_arc_position_set(SP_ARC(ac->item),
409
470
r.midpoint()[NR::X], r.midpoint()[NR::Y],
410
471
r.dimensions()[NR::X] / 2, r.dimensions()[NR::Y] / 2);
412
GString *xs = SP_PX_TO_METRIC_STRING(r.dimensions()[NR::X], desktop->namedview->getDefaultMetric());
413
GString *ys = SP_PX_TO_METRIC_STRING(r.dimensions()[NR::Y], desktop->namedview->getDefaultMetric());
414
ac->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("<b>Ellipse</b>: %s × %s; with <b>Ctrl</b> to make circle or integer-ratio ellipse; with <b>Shift</b> to draw around the starting point"), xs->str, ys->str);
473
double rdimx = r.dimensions()[NR::X];
474
double rdimy = r.dimensions()[NR::Y];
475
GString *xs = SP_PX_TO_METRIC_STRING(rdimx, desktop->namedview->getDefaultMetric());
476
GString *ys = SP_PX_TO_METRIC_STRING(rdimy, desktop->namedview->getDefaultMetric());
477
if (state & GDK_CONTROL_MASK) {
478
int ratio_x, ratio_y;
479
if (fabs (rdimx) > fabs (rdimy)) {
480
ratio_x = (int) rint (rdimx / rdimy);
484
ratio_y = (int) rint (rdimy / rdimx);
486
ac->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("<b>Ellipse</b>: %s × %s (constrained to ratio %d:%d); with <b>Shift</b> to draw around the starting point"), xs->str, ys->str, ratio_x, ratio_y);
488
ac->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("<b>Ellipse</b>: %s × %s; with <b>Ctrl</b> to make square or integer-ratio ellipse; with <b>Shift</b> to draw around the starting point"), xs->str, ys->str);
415
490
g_string_free(xs, FALSE);
416
491
g_string_free(ys, FALSE);