Code

dropper modes: replace undecipherable icons with text labels
[inkscape.git] / src / desktop.cpp
index 7cc77cbab82650bfe90d4850b4594c0cded016b3..f9d17b01ad6bbc5e938c8c9c5df0e2b8007427ab 100644 (file)
@@ -12,7 +12,7 @@
  *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
  *
  * Copyright (C) 2007 Jon A. Cruz
- * Copyright (C) 2006-2007 Johan Engelen
+ * Copyright (C) 2006-2008 Johan Engelen
  * Copyright (C) 2006 John Bintz
  * Copyright (C) 2004 MenTaLguY
  * Copyright (C) 1999-2002 Lauris Kaplinski
@@ -77,6 +77,8 @@
 #include "display/gnome-canvas-acetate.h"
 #include "display/sodipodi-ctrlrect.h"
 #include "display/sp-canvas-util.h"
+#include "display/canvas-temporary-item-list.h"
+#include "display/snap-indicator.h"
 #include "libnr/nr-matrix-div.h"
 #include "libnr/nr-rect-ops.h"
 #include "ui/dialog/dialog-manager.h"
@@ -85,6 +87,8 @@
 #include "layer-manager.h"
 #include "event-log.h"
 #include "display/canvas-grid.h"
+#include "widgets/desktop-widget.h"
+#include "box3d-context.h"
 
 #include "display/sp-canvas.h"
 
@@ -114,6 +118,8 @@ SPDesktop::SPDesktop() :
     event_context( 0 ),
     layer_manager( 0 ),
     event_log( 0 ),
+    temporary_item_list( 0 ),
+    snapindicator( 0 ),
     acetate( 0 ),
     main( 0 ),
     gridgroup( 0 ),
@@ -121,6 +127,7 @@ SPDesktop::SPDesktop() :
     drawing( 0 ),
     sketch( 0 ),
     controls( 0 ),
+    tempgroup ( 0 ),
     table( 0 ),
     page( 0 ),
     page_border( 0 ),
@@ -169,7 +176,7 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
     sp_document_ensure_up_to_date (document);
 
     /* Setup Dialog Manager */
-    _dlg_mgr = new Inkscape::UI::Dialog::DialogManager();
+    _dlg_mgr = &Inkscape::UI::Dialog::DialogManager::getInstance();
 
     dkey = sp_item_display_key_new (1);
 
@@ -216,6 +223,7 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
     guides = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
     sketch = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
     controls = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
+    tempgroup = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
 
     /* Push select tool to the bottom of stack */
     /** \todo
@@ -309,11 +317,25 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
     layer_manager = new Inkscape::LayerManager( this );
 
     showGrids(namedview->grids_visible, false);
+
+    temporary_item_list = new Inkscape::Display::TemporaryItemList( this );
+    snapindicator = new Inkscape::Display::SnapIndicator ( this );
 }
 
 
 void SPDesktop::destroy()
 {
+    if (snapindicator) {
+        delete snapindicator;
+        snapindicator = NULL;
+    }
+    if (temporary_item_list) {
+        delete temporary_item_list;
+        temporary_item_list = NULL;
+    }
+
+    namedview->hide(this);
+
     _activate_connection.disconnect();
     _deactivate_connection.disconnect();
     _sel_modified_connection.disconnect();
@@ -365,6 +387,28 @@ SPDesktop::~SPDesktop() {}
 //--------------------------------------------------------------------
 /* Public methods */
 
+
+/** Note that lifetime is measured in milliseconds
+* it is perfectly safe to ignore the returned pointer: the object is deleted by itself, so don't delete it elsewhere!
+* The return value should only be used as argument for SPDesktop::remove_temporary_canvasitem, because the object might be deleted already.
+*/
+Inkscape::Display::TemporaryItem *
+SPDesktop::add_temporary_canvasitem (SPCanvasItem *item, guint lifetime)
+{
+    return temporary_item_list->add_item(item, lifetime);
+}
+
+/** It is perfectly safe to call this function while the object has already been deleted due to a timeout.
+*/
+void
+SPDesktop::remove_temporary_canvasitem (Inkscape::Display::TemporaryItem * tempitem)
+{
+    // check for non-null temporary_item_list, because during destruction of desktop, some destructor might try to access this list!
+    if (tempitem && temporary_item_list) {
+        temporary_item_list->delete_item(tempitem);
+    }
+}
+
 void SPDesktop::setDisplayModeNormal()
 {
     SP_CANVAS_ARENA (drawing)->arena->rendermode = RENDERMODE_NORMAL;
@@ -499,6 +543,15 @@ SPDesktop::change_document (SPDocument *theDocument)
     selection->clear();
 
     setDocument (theDocument);
+
+    /* update the rulers, connect the desktop widget's signal to the new namedview etc.
+       (this can probably be done in a better way) */
+    Gtk::Window *parent = this->getToplevel();
+    g_assert(parent != NULL);
+    SPDesktopWidget *dtw = (SPDesktopWidget *) parent->get_data("desktopwidget");
+    if (dtw) dtw->desktop = this;
+    sp_desktop_widget_update_namedview(dtw);
+
     _namedview_modified (namedview, SP_OBJECT_MODIFIED_FLAG, this);
     _document_replaced_signal.emit (this, theDocument);
 }
@@ -643,7 +696,7 @@ SPDesktop::push_current_zoom (GList **history)
 }
 
 /**
- * Set viewbox.
+ * Set viewbox (x0, x1, y0 and y1 are in document pixels. Border is in screen pixels).
  */
 void
 SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double border, bool log)
@@ -671,7 +724,7 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double
         newscale = viewbox.dimensions()[NR::Y] / (y1 - y0);
     }
 
-    newscale = CLAMP(newscale, SP_DESKTOP_ZOOM_MIN, SP_DESKTOP_ZOOM_MAX);
+    newscale = CLAMP(newscale, SP_DESKTOP_ZOOM_MIN, SP_DESKTOP_ZOOM_MAX); // unit: 'screen pixels' per 'document pixels'
 
     int clear = FALSE;
     if (!NR_DF_TEST_CLOSE (newscale, scale, 1e-4 * scale)) {
@@ -682,13 +735,16 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double
         clear = TRUE;
     }
 
-    /* Calculate top left corner */
+    /* Calculate top left corner (in document pixels) */
     x0 = cx - 0.5 * viewbox.dimensions()[NR::X] / newscale;
     y1 = cy + 0.5 * viewbox.dimensions()[NR::Y] / newscale;
 
     /* Scroll */
     sp_canvas_scroll_to (canvas, x0 * newscale - border, y1 * -newscale - border, clear);
 
+    /*  update perspective lines if we are in the 3D box tool (so that infinite ones are shown correctly) */
+    sp_box3d_context_update_lines(event_context);
+
     _widget->updateRulers();
     _widget->updateScrollbars(expansion(_d2w));
     _widget->updateZoom();
@@ -927,6 +983,9 @@ SPDesktop::scroll_world (double dx, double dy, bool is_scrolling)
 
     sp_canvas_scroll_to(canvas, viewbox.min()[NR::X] - dx, viewbox.min()[NR::Y] - dy, FALSE, is_scrolling);
 
+    /*  update perspective lines if we are in the 3D box tool (so that infinite ones are shown correctly) */
+    sp_box3d_context_update_lines(event_context);
+
     _widget->updateRulers();
     _widget->updateScrollbars(expansion(_d2w));
 }
@@ -1086,9 +1145,11 @@ SPDesktop::shutdown()
 
 bool SPDesktop::onDeleteUI (GdkEventAny*)
 {
-       if(shutdown()) return true;
-       destroyWidget();
-       return false;
+    if(shutdown()) 
+        return true;
+
+    destroyWidget();
+    return false;
 }
 
 /**
@@ -1212,6 +1273,12 @@ void SPDesktop::showGrids(bool show, bool dirty_document)
     }
 }
 
+void SPDesktop::toggleSnapping()
+{
+    bool v = namedview->snap_manager.getSnapEnabledGlobally();
+    Inkscape::XML::Node *repr = SP_OBJECT_REPR(namedview);
+    sp_repr_set_boolean(repr, "inkscape:snap-global", !v);
+}
 
 //----------------------------------------------------------------------
 // Callback implementations. The virtual ones are connected by the view.
@@ -1529,15 +1596,15 @@ _update_snap_distances (SPDesktop *desktop)
     //tell all grid snappers
     for ( GSList const *l = nv.grids; l != NULL; l = l->next) {
         Inkscape::CanvasGrid *grid = (Inkscape::CanvasGrid*) l->data;
-        grid->snapper->setDistance(sp_convert_distance_full(nv.gridtolerance,
+        grid->snapper->setSnapperTolerance(sp_convert_distance_full(nv.gridtolerance,
                                                                       *nv.gridtoleranceunit,
                                                                       px));
     }
 
-    nv.snap_manager.guide.setDistance(sp_convert_distance_full(nv.guidetolerance,
+    nv.snap_manager.guide.setSnapperTolerance(sp_convert_distance_full(nv.guidetolerance,
                                                                        *nv.guidetoleranceunit,
                                                                        px));
-    nv.snap_manager.object.setDistance(sp_convert_distance_full(nv.objecttolerance,
+    nv.snap_manager.object.setSnapperTolerance(sp_convert_distance_full(nv.objecttolerance,
                                                                         *nv.objecttoleranceunit,
                                                                         px));
 }