~ubuntu-branches/debian/experimental/inkscape/experimental

« back to all changes in this revision

Viewing changes to src/arc-context.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-09-09 23:29:02 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20080909232902-c50iujhk1w79u8e7
Tags: 0.46-2.1
* Non-maintainer upload.
* Add upstream patch fixing a crash in the open dialog
  in the zh_CN.utf8 locale. Closes: #487623.
  Thanks to Luca Bruno for the patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
 *   Lauris Kaplinski <lauris@kaplinski.com>
9
9
 *   bulia byak <buliabyak@users.sf.net>
10
10
 *
 
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
14
15
 *
15
16
 * Released under GNU GPL, read the file 'COPYING' for more information
16
17
 */
39
40
#include "desktop.h"
40
41
#include "desktop-style.h"
41
42
#include "context-fns.h"
 
43
#include "verbs.h"
42
44
 
43
45
#include "arc-context.h"
44
46
 
225
227
 
226
228
    switch (event->type) {
227
229
        case GDK_BUTTON_PRESS:
228
 
            if (event->button.button == 1) {
 
230
            if (event->button.button == 1 && !event_context->space_panning) {
229
231
                Inkscape::setup_for_drag_start(desktop, event_context, event);
230
232
                ret = TRUE;
231
233
            }
256
258
 
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) {
260
262
 
261
263
                dragging = true;
262
264
                ac->center = Inkscape::setup_for_drag_start(desktop, event_context, event);
263
265
 
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();
 
268
                
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,
271
274
            }
272
275
            break;
273
276
        case GDK_MOTION_NOTIFY:
274
 
            if (dragging && event->motion.state && GDK_BUTTON1_MASK) {
 
277
            if (dragging && (event->motion.state & GDK_BUTTON1_MASK) && !event_context->space_panning) {
275
278
 
276
279
                if ( event_context->within_tolerance
277
280
                     && ( abs( (gint) event->motion.x - event_context->xp ) < event_context->tolerance )
284
287
                event_context->within_tolerance = false;
285
288
 
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));
 
291
                
 
292
                SnapManager const &m = desktop->namedview->snap_manager;            
 
293
                motion_dt = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, motion_dt, ac->item).getPoint();
 
294
 
288
295
                sp_arc_drag(ac, motion_dt, event->motion.state);
 
296
 
 
297
                gobble_motion_events(GDK_BUTTON1_MASK);
 
298
 
289
299
                ret = TRUE;
290
300
            }
291
301
            break;
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)
326
336
                case GDK_Meta_R:
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"),
330
 
                                               NULL);
 
337
                    if (!dragging) {
 
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"),
 
341
                                                   NULL);
 
342
                    }
331
343
                    break;
332
344
                case GDK_Up:
333
345
                case GDK_Down:
347
359
                case GDK_Escape:
348
360
                    sp_desktop_selection(desktop)->clear();
349
361
                    //TODO: make dragging escapable by Esc
 
362
                    break;
 
363
 
 
364
                case GDK_space:
 
365
                    if (dragging) {
 
366
                        sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
 
367
                                              event->button.time);
 
368
                        dragging = false;
 
369
                        if (!event_context->within_tolerance) {
 
370
                            // we've been dragging, finish the rect
 
371
                            sp_arc_finish(ac);
 
372
                        }
 
373
                        // do not return true, so that space would work switching to selector
 
374
                    }
 
375
                    break;
 
376
 
350
377
                default:
351
378
                    break;
352
379
            }
391
418
        }
392
419
 
393
420
        /* Create object */
394
 
        Inkscape::XML::Node *repr = sp_repr_new("svg:path");
 
421
        Inkscape::XML::Document *xml_doc = sp_document_repr_doc(desktop->doc());
 
422
        Inkscape::XML::Node *repr = xml_doc->createElement("svg:path");
395
423
        repr->setAttribute("sodipodi:type", "arc");
396
424
 
397
425
        /* Set style */
401
429
        Inkscape::GC::release(repr);
402
430
        ac->item->transform = SP_ITEM(desktop->currentRoot())->getRelativeTransform(desktop->currentLayer());
403
431
        ac->item->updateRepr();
404
 
    }
405
 
 
406
 
    NR::Rect const r = Inkscape::snap_rectangular_box(desktop, ac->item, pt, ac->center, state);
 
432
 
 
433
        sp_canvas_force_full_redraw_after_interruptions(desktop->canvas, 5);
 
434
    }
 
435
 
 
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
 
440
        ctrl_save = true;
 
441
        state = state ^ GDK_CONTROL_MASK;
 
442
    }
 
443
    NR::Rect r = Inkscape::snap_rectangular_box(desktop, ac->item, pt, ac->center, state);
 
444
    if (ctrl_save) {
 
445
        state = state ^ GDK_CONTROL_MASK;
 
446
    }
 
447
 
 
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();
 
452
        if (!ctrl_save) {
 
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);
 
459
            }
 
460
        } else {
 
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);
 
466
        }
 
467
    }
407
468
 
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);
411
472
 
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 &#215; %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);
 
481
            ratio_y = 1;
 
482
        } else {
 
483
            ratio_x = 1;
 
484
            ratio_y = (int) rint (rdimy / rdimx);
 
485
        }
 
486
        ac->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("<b>Ellipse</b>: %s &#215; %s (constrained to ratio %d:%d); with <b>Shift</b> to draw around the starting point"), xs->str, ys->str, ratio_x, ratio_y);
 
487
    } else {
 
488
        ac->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("<b>Ellipse</b>: %s &#215; %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);
 
489
    }
415
490
    g_string_free(xs, FALSE);
416
491
    g_string_free(ys, FALSE);
417
492
}
425
500
 
426
501
        SP_OBJECT(ac->item)->updateRepr();
427
502
 
 
503
        sp_canvas_end_forced_full_redraws(desktop->canvas);
 
504
        
428
505
        sp_desktop_selection(desktop)->set(ac->item);
429
 
        sp_document_done(sp_desktop_document(desktop));
 
506
        sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_ARC, 
 
507
                         _("Create ellipse"));
430
508
 
431
509
        ac->item = NULL;
432
510
    }