diff --git a/src/desktop.cpp b/src/desktop.cpp
index 4727f3e511e564de3194df3cf7fc9a2e78eea74d..83a6f40219717352957ad0f7659cd591290da120 100644 (file)
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
* John Bintz <jcoswell@coswellproductions.org>
* Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
*
- * Copyright (C) 2006-2007 Johan Engelen
+ * Copyright (C) 2007 Jon A. Cruz
+ * Copyright (C) 2006-2008 Johan Engelen
* Copyright (C) 2006 John Bintz
* Copyright (C) 2004 MenTaLguY
* Copyright (C) 1999-2002 Lauris Kaplinski
#include <sigc++/functors/mem_fun.h>
#include <gtkmm.h>
+#include <2geom/rect.h>
#include "macros.h"
#include "inkscape-private.h"
#include "desktop.h"
#include "sp-namedview.h"
#include "color.h"
#include "sp-item-group.h"
-#include "prefs-utils.h"
+#include "preferences.h"
#include "object-hierarchy.h"
#include "helper/units.h"
#include "display/canvas-arena.h"
#include "display/gnome-canvas-acetate.h"
#include "display/sodipodi-ctrlrect.h"
#include "display/sp-canvas-util.h"
-#include "libnr/nr-matrix-div.h"
-#include "libnr/nr-rect-ops.h"
+#include "display/canvas-temporary-item-list.h"
+#include "display/snap-indicator.h"
#include "ui/dialog/dialog-manager.h"
#include "xml/repr.h"
#include "message-context.h"
+#include "device-manager.h"
+#include "layer-fns.h"
#include "layer-manager.h"
#include "event-log.h"
#include "display/canvas-grid.h"
+#include "widgets/desktop-widget.h"
+#include "box3d-context.h"
+
+// TODO those includes are only for node tool quick zoom. Remove them after fixing it.
+#include "ui/tool/node-tool.h"
+#include "ui/tool/control-point-selection.h"
+
+#include "display/sp-canvas.h"
namespace Inkscape { namespace XML { class Node; }}
@@ -96,59 +108,77 @@ static void _layer_hierarchy_changed(SPObject *top, SPObject *bottom, SPDesktop
static void _reconstruction_start(SPDesktop * desktop);
static void _reconstruction_finish(SPDesktop * desktop);
static void _namedview_modified (SPObject *obj, guint flags, SPDesktop *desktop);
-static void _update_snap_distances (SPDesktop *desktop);
/**
* Return new desktop object.
* \pre namedview != NULL.
* \pre canvas != NULL.
*/
-SPDesktop::SPDesktop()
-{
- _dlg_mgr = NULL;
- _widget = 0;
- namedview = NULL;
- selection = NULL;
- acetate = NULL;
- main = NULL;
- grid = NULL;
- guides = NULL;
- drawing = NULL;
- sketch = NULL;
- controls = NULL;
- event_context = 0;
- layer_manager = 0;
-
- _d2w.set_identity();
- _w2d.set_identity();
- _doc2dt = NR::Matrix(NR::scale(1, -1));
-
- guides_active = false;
-
- zooms_past = NULL;
- zooms_future = NULL;
-
- is_fullscreen = false;
- waiting_cursor = false;
-
- gr_item = NULL;
- gr_point_type = 0;
- gr_point_i = 0;
- gr_fill_or_stroke = true;
-
- _layer_hierarchy = NULL;
- _active = false;
-
- selection = Inkscape::GC::release (new Inkscape::Selection (this));
+SPDesktop::SPDesktop() :
+ _dlg_mgr( 0 ),
+ namedview( 0 ),
+ canvas( 0 ),
+ selection( 0 ),
+ event_context( 0 ),
+ layer_manager( 0 ),
+ event_log( 0 ),
+ temporary_item_list( 0 ),
+ snapindicator( 0 ),
+ acetate( 0 ),
+ main( 0 ),
+ gridgroup( 0 ),
+ guides( 0 ),
+ drawing( 0 ),
+ sketch( 0 ),
+ controls( 0 ),
+ tempgroup ( 0 ),
+ table( 0 ),
+ page( 0 ),
+ page_border( 0 ),
+ current( 0 ),
+ _focusMode(false),
+ zooms_past( 0 ),
+ zooms_future( 0 ),
+ dkey( 0 ),
+ number( 0 ),
+ window_state(0),
+ interaction_disabled_counter( 0 ),
+ waiting_cursor( false ),
+ guides_active( false ),
+ gr_item( 0 ),
+ gr_point_type( 0 ),
+ gr_point_i( 0 ),
+ gr_fill_or_stroke( true ),
+ _layer_hierarchy( 0 ),
+ _reconstruction_old_layer_id( 0 ),
+ _display_mode(Inkscape::RENDERMODE_NORMAL),
+ _widget( 0 ),
+ _inkscape( 0 ),
+ _guides_message_context( 0 ),
+ _active( false ),
+ _w2d(),
+ _d2w(),
+ _doc2dt( Geom::Scale(1, -1) ),
+ grids_visible( false )
+{
+ _d2w.setIdentity();
+ _w2d.setIdentity();
+
+ selection = Inkscape::GC::release( new Inkscape::Selection(this) );
}
void
-SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
-
+SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWidgetInterface *widget)
{
+ _widget = widget;
+
+ // Temporary workaround for link order issues:
+ Inkscape::DeviceManager::getManager().getDevices();
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+
_guides_message_context = new Inkscape::MessageContext(const_cast<Inkscape::MessageStack*>(messageStack()));
- current = sp_repr_css_attr_inherited (inkscape_get_repr (INKSCAPE, "desktop"), "style");
+ current = prefs->getStyle("/desktop/style");
namedview = nv;
canvas = 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);
g_signal_connect (G_OBJECT (main), "event", G_CALLBACK (sp_desktop_root_handler), this);
table = sp_canvas_item_new (main, SP_TYPE_CTRLRECT, NULL);
- SP_CTRLRECT(table)->setRectangle(NR::Rect(NR::Point(-80000, -80000), NR::Point(80000, 80000)));
+ SP_CTRLRECT(table)->setRectangle(Geom::Rect(Geom::Point(-80000, -80000), Geom::Point(80000, 80000)));
SP_CTRLRECT(table)->setColor(0x00000000, true, 0x00000000);
sp_canvas_item_move_to_z (table, 0);
drawing = sp_canvas_item_new (main, SP_TYPE_CANVAS_ARENA, NULL);
g_signal_connect (G_OBJECT (drawing), "arena_event", G_CALLBACK (_arena_handler), this);
- SP_CANVAS_ARENA (drawing)->arena->delta = prefs_get_double_attribute ("options.cursortolerance", "value", 1.0); // default is 1 px
+ SP_CANVAS_ARENA (drawing)->arena->delta = prefs->getDouble("/options/cursortolerance/value", 1.0); // default is 1 px
- if (prefs_get_int_attribute("options.startmode", "outline", 0)) {
+ if (prefs->getBool("/options/startmode/outline")) {
// Start in outline mode
setDisplayModeOutline();
} else {
setDisplayModeNormal();
}
- grid = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
+ // The order in which these canvas items are added determines the z-order. It's therefore
+ // important to add the tempgroup (which will contain the snapindicator) before adding the
+ // controls. Only this way one will be able to quickly (before the snap indicator has
+ // disappeared) reselect a node after snapping it. If the z-order is wrong however, this
+ // will not work (the snap indicator is on top of the node handler; is the snapindicator
+ // being selected? or does it intercept some of the events that should have gone to the
+ // node handler? see bug https://bugs.launchpad.net/inkscape/+bug/414142)
+ gridgroup = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
guides = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
sketch = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
+ tempgroup = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
controls = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
/* Push select tool to the bottom of stack */
* call "set" instead of "push". Can we assume that there is only one
* context ever?
*/
- push_event_context (SP_TYPE_SELECT_CONTEXT, "tools.select", SP_EVENT_CONTEXT_STATIC);
+ push_event_context (SP_TYPE_SELECT_CONTEXT, "/tools/select", SP_EVENT_CONTEXT_STATIC);
// display rect and zoom are now handled in sp_desktop_widget_realize()
- NR::Rect const d(NR::Point(0.0, 0.0),
- NR::Point(sp_document_width(document), sp_document_height(document)));
+ Geom::Rect const d(Geom::Point(0.0, 0.0),
+ Geom::Point(sp_document_width(document), sp_document_height(document)));
SP_CTRLRECT(page)->setRectangle(d);
SP_CTRLRECT(page_border)->setRectangle(d);
SP_ITEM_SHOW_DISPLAY);
if (ai) {
nr_arena_item_add_child (SP_CANVAS_ARENA (drawing)->root, ai, NULL);
- nr_arena_item_unref (ai);
}
namedview->show(this);
_reconstruction_finish_connection =
document->connectReconstructionFinish(sigc::bind(sigc::ptr_fun(_reconstruction_finish), this));
_reconstruction_old_layer_id = NULL;
-
- _commit_connection = document->connectCommit(sigc::mem_fun(*this, &SPDesktop::updateNow));
-
+
// ?
// sp_active_desktop_set (desktop);
_inkscape = INKSCAPE;
/* setup LayerManager */
// (Setting up after the connections are all in place, as it may use some of them)
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;
+ }
+
+ if (selection) {
+ delete selection;
+ selection = NULL;
+ }
+
+ namedview->hide(this);
+
_activate_connection.disconnect();
_deactivate_connection.disconnect();
_sel_modified_connection.disconnect();
if (_layer_hierarchy) {
delete _layer_hierarchy;
+// _layer_hierarchy = NULL; //this should be here, but commented to find other bug somewhere else.
+ }
+
+ if (layer_manager) {
+ delete layer_manager;
+ layer_manager = NULL;
}
if (_inkscape) {
//--------------------------------------------------------------------
/* Public methods */
-void SPDesktop::setDisplayModeNormal()
+
+/* These methods help for temporarily showing things on-canvas.
+ * The *only* valid use of the TemporaryItem* that you get from add_temporary_canvasitem
+ * is when you want to prematurely remove the item from the canvas, by calling
+ * desktop->remove_temporary_canvasitem(tempitem).
+ */
+/** Note that lifetime is measured in milliseconds
+ * One should *not* keep a reference to the SPCanvasItem, the temporary item code will
+ * delete the object for you and the reference will become invalid without you knowing it.
+ * It is perfectly safe to ignore the returned pointer: the object is deleted by itself, so don't delete it elsewhere!
+ * The *only* valid use of the returned TemporaryItem* is as argument for SPDesktop::remove_temporary_canvasitem,
+ * because the object might be deleted already without you knowing it.
+ * move_to_bottom = true by default so the item does not interfere with handling of other items on the canvas like nodes.
+ */
+Inkscape::Display::TemporaryItem *
+SPDesktop::add_temporary_canvasitem (SPCanvasItem *item, guint lifetime, bool move_to_bottom)
{
- SP_CANVAS_ARENA (drawing)->arena->rendermode = RENDERMODE_NORMAL;
- canvas->rendermode = RENDERMODE_NORMAL; // canvas needs that for choosing the best buffer size
- displayMode = RENDERMODE_NORMAL;
- sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw
- _widget->setTitle(SP_DOCUMENT_NAME(sp_desktop_document(this)));
+ if (move_to_bottom) {
+ sp_canvas_item_move_to_z(item, 0);
+ }
+
+ return temporary_item_list->add_item(item, lifetime);
}
-void SPDesktop::setDisplayModeOutline()
+/** 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)
{
- SP_CANVAS_ARENA (drawing)->arena->rendermode = RENDERMODE_OUTLINE;
- canvas->rendermode = RENDERMODE_OUTLINE; // canvas needs that for choosing the best buffer size
- displayMode = RENDERMODE_OUTLINE;
+ // 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::_setDisplayMode(Inkscape::RenderMode mode) {
+ SP_CANVAS_ARENA (drawing)->arena->rendermode = mode;
+ canvas->rendermode = mode;
+ _display_mode = mode;
sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw
_widget->setTitle(SP_DOCUMENT_NAME(sp_desktop_document(this)));
}
-void SPDesktop::displayModeToggle()
-{
- if (displayMode == RENDERMODE_OUTLINE)
- setDisplayModeNormal();
- else
- setDisplayModeOutline();
+void SPDesktop::displayModeToggle() {
+ switch (_display_mode) {
+ case Inkscape::RENDERMODE_NORMAL:
+ _setDisplayMode(Inkscape::RENDERMODE_NO_FILTERS);
+ break;
+ case Inkscape::RENDERMODE_NO_FILTERS:
+ _setDisplayMode(Inkscape::RENDERMODE_OUTLINE);
+ break;
+ case Inkscape::RENDERMODE_OUTLINE:
+ _setDisplayMode(Inkscape::RENDERMODE_NORMAL);
+ break;
+// case Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW:
+ default:
+ _setDisplayMode(Inkscape::RENDERMODE_NORMAL);
+ }
}
/**
/**
* Sets the current layer of the desktop.
- *
+ *
* Make \a object the top layer.
*/
void SPDesktop::setCurrentLayer(SPObject *object) {
_layer_hierarchy->setBottom(object);
}
+void SPDesktop::toggleLayerSolo(SPObject *object) {
+ g_return_if_fail(SP_IS_GROUP(object));
+ g_return_if_fail( currentRoot() == object || (currentRoot() && currentRoot()->isAncestorOf(object)) );
+
+ bool othersShowing = false;
+ std::vector<SPObject*> layers;
+ for ( SPObject* obj = Inkscape::next_layer(currentRoot(), object); obj; obj = Inkscape::next_layer(currentRoot(), obj) ) {
+ layers.push_back(obj);
+ othersShowing |= !SP_ITEM(obj)->isHidden();
+ }
+ for ( SPObject* obj = Inkscape::previous_layer(currentRoot(), object); obj; obj = Inkscape::previous_layer(currentRoot(), obj) ) {
+ layers.push_back(obj);
+ othersShowing |= !SP_ITEM(obj)->isHidden();
+ }
+
+
+ if ( SP_ITEM(object)->isHidden() ) {
+ SP_ITEM(object)->setHidden(false);
+ }
+
+ for ( std::vector<SPObject*>::iterator it = layers.begin(); it != layers.end(); ++it ) {
+ SP_ITEM(*it)->setHidden(othersShowing);
+ }
+}
+
/**
* Return layer that contains \a object.
*/
*/
bool SPDesktop::isWithinViewport (SPItem *item) const
{
- NR::Rect const viewport = get_display_area();
- NR::Maybe<NR::Rect> const bbox = sp_item_bbox_desktop(item);
+ Geom::Rect const viewport = get_display_area();
+ Geom::OptRect const bbox = sp_item_bbox_desktop(item);
if (bbox) {
return viewport.contains(*bbox);
} else {
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;
+ }
+ dtw->updateNamedview();
+
_namedview_modified (namedview, SP_OBJECT_MODIFIED_FLAG, this);
_document_replaced_signal.emit (this, theDocument);
}
while (event_context) {
ec = event_context;
sp_event_context_deactivate (ec);
- event_context = ec->next;
+ // we have to keep event_context valid during destruction - otherwise writing
+ // destructors is next to impossible
+ SPEventContext *next = ec->next;
sp_event_context_finish (ec);
g_object_unref (G_OBJECT (ec));
+ event_context = next;
}
- Inkscape::XML::Node *repr = (config) ? inkscape_get_repr (_inkscape, config) : NULL;
- ec = sp_event_context_new (type, this, repr, SP_EVENT_CONTEXT_STATIC);
+ // The event_context will be null. This means that it will be impossible
+ // to process any event invoked by the lines below. See for example bug
+ // LP #622350. Cutting and undoing again in the node tool resets the event
+ // context to the node tool. In this bug the line bellow invokes GDK_LEAVE_NOTIFY
+ // events which cannot be handled and must be discarded.
+ ec = sp_event_context_new (type, this, config, SP_EVENT_CONTEXT_STATIC);
ec->next = event_context;
event_context = ec;
+ // Now the event_context has been set again and we can process all events again
sp_event_context_activate (ec);
_event_context_changed_signal.emit (this, ec);
}
SPDesktop::push_event_context (GtkType type, const gchar *config, unsigned int key)
{
SPEventContext *ref, *ec;
- Inkscape::XML::Node *repr;
if (event_context && event_context->key == key) return;
ref = event_context;
@@ -529,8 +668,7 @@ SPDesktop::push_event_context (GtkType type, const gchar *config, unsigned int k
}
if (event_context) sp_event_context_deactivate (event_context);
- repr = (config) ? inkscape_get_repr (INKSCAPE, config) : NULL;
- ec = sp_event_context_new (type, this, repr, key);
+ ec = sp_event_context_new (type, this, config, key);
ec->next = event_context;
event_context = ec;
sp_event_context_activate (ec);
@@ -541,7 +679,7 @@ SPDesktop::push_event_context (GtkType type, const gchar *config, unsigned int k
* Sets the coordinate status to a given point
*/
void
-SPDesktop::set_coordinate_status (NR::Point p) {
+SPDesktop::set_coordinate_status (Geom::Point p) {
_widget->setCoordinateStatus(p);
}
* \see sp_document_item_from_list_at_point_bottom()
*/
SPItem *
-SPDesktop::item_from_list_at_point_bottom (const GSList *list, NR::Point const p) const
+SPDesktop::item_from_list_at_point_bottom (const GSList *list, Geom::Point const p) const
{
g_return_val_if_fail (doc() != NULL, NULL);
return sp_document_item_from_list_at_point_bottom (dkey, SP_GROUP (doc()->root), list, p);
@@ -559,7 +697,7 @@ SPDesktop::item_from_list_at_point_bottom (const GSList *list, NR::Point const p
* \see sp_document_item_at_point()
*/
SPItem *
-SPDesktop::item_at_point (NR::Point const p, bool into_groups, SPItem *upto) const
+SPDesktop::item_at_point (Geom::Point const p, bool into_groups, SPItem *upto) const
{
g_return_val_if_fail (doc() != NULL, NULL);
return sp_document_item_at_point (doc(), dkey, p, into_groups, upto);
@@ -569,7 +707,7 @@ SPDesktop::item_at_point (NR::Point const p, bool into_groups, SPItem *upto) con
* \see sp_document_group_at_point()
*/
SPItem *
-SPDesktop::group_at_point (NR::Point const p) const
+SPDesktop::group_at_point (Geom::Point const p) const
{
g_return_val_if_fail (doc() != NULL, NULL);
return sp_document_group_at_point (doc(), dkey, p);
* \brief Returns the mouse point in document coordinates; if mouse is
* outside the canvas, returns the center of canvas viewpoint
*/
-NR::Point
+Geom::Point
SPDesktop::point() const
{
- NR::Point p = _widget->getPointer();
- NR::Point pw = sp_canvas_window_to_world (canvas, p);
+ Geom::Point p = _widget->getPointer();
+ Geom::Point pw = sp_canvas_window_to_world (canvas, p);
p = w2d(pw);
- NR::Rect const r = canvas->getViewbox();
+ Geom::Rect const r = canvas->getViewbox();
- NR::Point r0 = w2d(r.min());
- NR::Point r1 = w2d(r.max());
+ Geom::Point r0 = w2d(r.min());
+ Geom::Point r1 = w2d(r.max());
- if (p[NR::X] >= r0[NR::X] &&
- p[NR::X] <= r1[NR::X] &&
- p[NR::Y] >= r1[NR::Y] &&
- p[NR::Y] <= r0[NR::Y])
+ if (p[Geom::X] >= r0[Geom::X] &&
+ p[Geom::X] <= r1[Geom::X] &&
+ p[Geom::Y] >= r1[Geom::Y] &&
+ p[Geom::Y] <= r0[Geom::Y])
{
return p;
} else {
void
SPDesktop::push_current_zoom (GList **history)
{
- NR::Rect const area = get_display_area();
+ Geom::Rect const area = get_display_area();
NRRect *old_zoom = g_new(NRRect, 1);
- old_zoom->x0 = area.min()[NR::X];
- old_zoom->x1 = area.max()[NR::X];
- old_zoom->y0 = area.min()[NR::Y];
- old_zoom->y1 = area.max()[NR::Y];
+ old_zoom->x0 = area.min()[Geom::X];
+ old_zoom->x1 = area.max()[Geom::X];
+ old_zoom->y0 = area.min()[Geom::Y];
+ old_zoom->y1 = area.max()[Geom::Y];
if ( *history == NULL
|| !( ( ((NRRect *) ((*history)->data))->x0 == old_zoom->x0 ) &&
( ((NRRect *) ((*history)->data))->x1 == old_zoom->x1 ) &&
}
/**
- * 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)
@@ -644,55 +782,61 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double
double const cx = 0.5 * (x0 + x1);
double const cy = 0.5 * (y0 + y1);
- NR::Rect const viewbox = NR::expand(canvas->getViewbox(), border);
+ // FIXME: This 2geom idiom doesn't allow us to declare dbox const
+ Geom::Rect viewbox = canvas->getViewbox();
+ viewbox.expandBy(-border);
- double scale = expansion(_d2w);
+ double scale = _d2w.descrim();
double newscale;
- if (((x1 - x0) * viewbox.dimensions()[NR::Y]) > ((y1 - y0) * viewbox.dimensions()[NR::X])) {
- newscale = viewbox.dimensions()[NR::X] / (x1 - x0);
+ if (((x1 - x0) * viewbox.dimensions()[Geom::Y]) > ((y1 - y0) * viewbox.dimensions()[Geom::X])) {
+ newscale = viewbox.dimensions()[Geom::X] / (x1 - x0);
} else {
- newscale = viewbox.dimensions()[NR::Y] / (y1 - y0);
+ newscale = viewbox.dimensions()[Geom::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)) {
- /* Set zoom factors */
- _d2w = NR::Matrix(NR::scale(newscale, -newscale));
- _w2d = NR::Matrix(NR::scale(1/newscale, 1/-newscale));
+ // zoom changed - set new zoom factors
+ _d2w = Geom::Scale(newscale, -newscale);
+ _w2d = Geom::Scale(1/newscale, 1/-newscale);
sp_canvas_item_affine_absolute(SP_CANVAS_ITEM(main), _d2w);
clear = TRUE;
+ signal_zoom_changed.emit(_d2w.descrim());
}
- /* Calculate top left corner */
- x0 = cx - 0.5 * viewbox.dimensions()[NR::X] / newscale;
- y1 = cy + 0.5 * viewbox.dimensions()[NR::Y] / newscale;
+ /* Calculate top left corner (in document pixels) */
+ x0 = cx - 0.5 * viewbox.dimensions()[Geom::X] / newscale;
+ y1 = cy + 0.5 * viewbox.dimensions()[Geom::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->updateScrollbars(_d2w.descrim());
_widget->updateZoom();
}
-void SPDesktop::set_display_area(NR::Rect const &a, NR::Coord b, bool log)
+void SPDesktop::set_display_area(Geom::Rect const &a, Geom::Coord b, bool log)
{
- set_display_area(a.min()[NR::X], a.min()[NR::Y], a.max()[NR::X], a.max()[NR::Y], b, log);
+ set_display_area(a.min()[Geom::X], a.min()[Geom::Y], a.max()[Geom::X], a.max()[Geom::Y], b, log);
}
/**
* Return viewbox dimensions.
*/
-NR::Rect SPDesktop::get_display_area() const
+Geom::Rect SPDesktop::get_display_area() const
{
- NR::Rect const viewbox = canvas->getViewbox();
+ Geom::Rect const viewbox = canvas->getViewbox();
double const scale = _d2w[0];
- return NR::Rect(NR::Point(viewbox.min()[NR::X] / scale, viewbox.max()[NR::Y] / -scale),
- NR::Point(viewbox.max()[NR::X] / scale, viewbox.min()[NR::Y] / -scale));
+ return Geom::Rect(Geom::Point(viewbox.min()[Geom::X] / scale, viewbox.max()[Geom::Y] / -scale),
+ Geom::Point(viewbox.max()[Geom::X] / scale, viewbox.min()[Geom::Y] / -scale));
}
/**
zooms_future = g_list_remove (zooms_future, ((NRRect *) zooms_future->data));
}
+/** \brief Performs a quick zoom into what the user is working on
+ \param enable Whether we're going in or out of quick zoom
+
+*/
+void
+SPDesktop::zoom_quick (bool enable)
+{
+ if (enable == _quick_zoom_enabled) {
+ return;
+ }
+
+ if (enable == true) {
+ _quick_zoom_stored_area = get_display_area();
+ bool zoomed = false;
+
+ // TODO This needs to migrate into the node tool, but currently the design
+ // of this method is sufficiently wrong to prevent this.
+ if (!zoomed && INK_IS_NODE_TOOL(event_context)) {
+ InkNodeTool *nt = static_cast<InkNodeTool*>(event_context);
+ if (!nt->_selected_nodes->empty()) {
+ Geom::Rect nodes = *nt->_selected_nodes->bounds();
+ double area = nodes.area();
+ // do not zoom if a single cusp node is selected aand the bounds
+ // have zero area.
+ if (!Geom::are_near(area, 0) && area * 2.0 < _quick_zoom_stored_area.area()) {
+ set_display_area(nodes, true);
+ zoomed = true;
+ }
+ }
+ }
+
+ if (!zoomed) {
+ Geom::OptRect const d = selection->bounds();
+ if (d && d->area() * 2.0 < _quick_zoom_stored_area.area()) {
+ set_display_area(*d, true);
+ zoomed = true;
+ }
+ }
+
+ if (!zoomed) {
+ zoom_relative(_quick_zoom_stored_area.midpoint()[Geom::X], _quick_zoom_stored_area.midpoint()[Geom::Y], 2.0);
+ zoomed = true;
+ }
+ } else {
+ set_display_area(_quick_zoom_stored_area, false);
+ }
+
+ _quick_zoom_enabled = enable;
+ return;
+}
+
/**
* Zoom to point with absolute zoom factor.
*/
@@ -756,13 +951,13 @@ SPDesktop::zoom_absolute_keep_point (double cx, double cy, double px, double py,
// maximum or minimum zoom reached, but there's no exact equality because of rounding errors;
// this check prevents "sliding" when trying to zoom in at maximum zoom;
/// \todo someone please fix calculations properly and remove this hack
- if (fabs(expansion(_d2w) - zoom) < 0.0001*zoom && (fabs(SP_DESKTOP_ZOOM_MAX - zoom) < 0.01 || fabs(SP_DESKTOP_ZOOM_MIN - zoom) < 0.000001))
+ if (fabs(_d2w.descrim() - zoom) < 0.0001*zoom && (fabs(SP_DESKTOP_ZOOM_MAX - zoom) < 0.01 || fabs(SP_DESKTOP_ZOOM_MIN - zoom) < 0.000001))
return;
- NR::Rect const viewbox = canvas->getViewbox();
+ Geom::Rect const viewbox = canvas->getViewbox();
- double const width2 = viewbox.dimensions()[NR::X] / zoom;
- double const height2 = viewbox.dimensions()[NR::Y] / zoom;
+ double const width2 = viewbox.dimensions()[Geom::X] / zoom;
+ double const height2 = viewbox.dimensions()[Geom::Y] / zoom;
set_display_area(cx - px * width2,
cy - py * height2,
void
SPDesktop::zoom_relative_keep_point (double cx, double cy, double zoom)
{
- NR::Rect const area = get_display_area();
+ Geom::Rect const area = get_display_area();
- if (cx < area.min()[NR::X]) {
- cx = area.min()[NR::X];
+ if (cx < area.min()[Geom::X]) {
+ cx = area.min()[Geom::X];
}
- if (cx > area.max()[NR::X]) {
- cx = area.max()[NR::X];
+ if (cx > area.max()[Geom::X]) {
+ cx = area.max()[Geom::X];
}
- if (cy < area.min()[NR::Y]) {
- cy = area.min()[NR::Y];
+ if (cy < area.min()[Geom::Y]) {
+ cy = area.min()[Geom::Y];
}
- if (cy > area.max()[NR::Y]) {
- cy = area.max()[NR::Y];
+ if (cy > area.max()[Geom::Y]) {
+ cy = area.max()[Geom::Y];
}
- gdouble const scale = expansion(_d2w) * zoom;
- double const px = (cx - area.min()[NR::X]) / area.dimensions()[NR::X];
- double const py = (cy - area.min()[NR::Y]) / area.dimensions()[NR::Y];
+ gdouble const scale = _d2w.descrim() * zoom;
+ double const px = (cx - area.min()[Geom::X]) / area.dimensions()[Geom::X];
+ double const py = (cy - area.min()[Geom::Y]) / area.dimensions()[Geom::Y];
zoom_absolute_keep_point(cx, cy, px, py, scale);
}
void
SPDesktop::zoom_relative (double cx, double cy, double zoom)
{
- gdouble scale = expansion(_d2w) * zoom;
+ gdouble scale = _d2w.descrim() * zoom;
zoom_absolute (cx, cy, scale);
}
void
SPDesktop::zoom_page()
{
- NR::Rect d(NR::Point(0, 0),
- NR::Point(sp_document_width(doc()), sp_document_height(doc())));
+ Geom::Rect d(Geom::Point(0, 0),
+ Geom::Point(sp_document_width(doc()), sp_document_height(doc())));
- if (d.isEmpty(1.0)) {
+ if (d.minExtent() < 1.0) {
return;
}
void
SPDesktop::zoom_page_width()
{
- NR::Rect const a = get_display_area();
+ Geom::Rect const a = get_display_area();
if (sp_document_width(doc()) < 1.0) {
return;
}
- NR::Rect d(NR::Point(0, a.midpoint()[NR::Y]),
- NR::Point(sp_document_width(doc()), a.midpoint()[NR::Y]));
+ Geom::Rect d(Geom::Point(0, a.midpoint()[Geom::Y]),
+ Geom::Point(sp_document_width(doc()), a.midpoint()[Geom::Y]));
set_display_area(d, 10);
}
void
SPDesktop::zoom_selection()
{
- NR::Maybe<NR::Rect> const d = selection->bounds();
+ Geom::OptRect const d = selection->bounds();
- if ( !d || d->isEmpty(0.1) ) {
+ if ( !d || d->minExtent() < 0.1 ) {
return;
}
SPItem *docitem = SP_ITEM (sp_document_root (doc()));
g_return_if_fail (docitem != NULL);
- NR::Maybe<NR::Rect> d = sp_item_bbox_desktop(docitem);
+ Geom::OptRect d = sp_item_bbox_desktop(docitem);
/* Note that the second condition here indicates that
** there are no items in the drawing.
*/
- if ( !d || d->isEmpty(1.0) ) {
+ if ( !d || d->minExtent() < 0.1 ) {
return;
}
set_display_area(*d, 10);
}
+/**
+ * Scroll canvas by specific coordinate amount in svg coordinates.
+ */
+void
+SPDesktop::scroll_world_in_svg_coords (double dx, double dy, bool is_scrolling)
+{
+ double scale = _d2w.descrim();
+ scroll_world(dx*scale, dy*scale, is_scrolling);
+}
+
/**
* Scroll canvas by specific coordinate amount.
*/
{
g_assert(_widget);
- NR::Rect const viewbox = canvas->getViewbox();
+ Geom::Rect const viewbox = canvas->getViewbox();
- sp_canvas_scroll_to(canvas, viewbox.min()[NR::X] - dx, viewbox.min()[NR::Y] - dy, FALSE, is_scrolling);
+ sp_canvas_scroll_to(canvas, viewbox.min()[Geom::X] - dx, viewbox.min()[Geom::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));
+ _widget->updateScrollbars(_d2w.descrim());
}
bool
-SPDesktop::scroll_to_point (NR::Point const *p, gdouble autoscrollspeed)
+SPDesktop::scroll_to_point (Geom::Point const &p, gdouble autoscrollspeed)
{
- gdouble autoscrolldistance = (gdouble) prefs_get_int_attribute_limited ("options.autoscrolldistance", "value", 0, -1000, 10000);
+ using Geom::X;
+ using Geom::Y;
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gdouble autoscrolldistance = (gdouble) prefs->getIntLimited("/options/autoscrolldistance/value", 0, -1000, 10000);
// autoscrolldistance is in screen pixels, but the display area is in document units
- autoscrolldistance /= expansion(_d2w);
- NR::Rect const dbox = NR::expand(get_display_area(), -autoscrolldistance);
+ autoscrolldistance /= _d2w.descrim();
+ // FIXME: This 2geom idiom doesn't allow us to declare dbox const
+ Geom::Rect dbox = get_display_area();
+ dbox.expandBy(-autoscrolldistance);
- if (!((*p)[NR::X] > dbox.min()[NR::X] && (*p)[NR::X] < dbox.max()[NR::X]) ||
- !((*p)[NR::Y] > dbox.min()[NR::Y] && (*p)[NR::Y] < dbox.max()[NR::Y]) ) {
+ if (!(p[X] > dbox.min()[X] && p[X] < dbox.max()[X]) ||
+ !(p[Y] > dbox.min()[Y] && p[Y] < dbox.max()[Y]) ) {
- NR::Point const s_w( (*p) * _d2w );
+ Geom::Point const s_w( p * (Geom::Matrix)_d2w );
gdouble x_to;
- if ((*p)[NR::X] < dbox.min()[NR::X])
- x_to = dbox.min()[NR::X];
- else if ((*p)[NR::X] > dbox.max()[NR::X])
- x_to = dbox.max()[NR::X];
+ if (p[X] < dbox.min()[X])
+ x_to = dbox.min()[X];
+ else if (p[X] > dbox.max()[X])
+ x_to = dbox.max()[X];
else
- x_to = (*p)[NR::X];
+ x_to = p[X];
gdouble y_to;
- if ((*p)[NR::Y] < dbox.min()[NR::Y])
- y_to = dbox.min()[NR::Y];
- else if ((*p)[NR::Y] > dbox.max()[NR::Y])
- y_to = dbox.max()[NR::Y];
+ if (p[Y] < dbox.min()[Y])
+ y_to = dbox.min()[Y];
+ else if (p[Y] > dbox.max()[Y])
+ y_to = dbox.max()[Y];
else
- y_to = (*p)[NR::Y];
+ y_to = p[Y];
- NR::Point const d_dt(x_to, y_to);
- NR::Point const d_w( d_dt * _d2w );
- NR::Point const moved_w( d_w - s_w );
+ Geom::Point const d_dt(x_to, y_to);
+ Geom::Point const d_w( d_dt * _d2w );
+ Geom::Point const moved_w( d_w - s_w );
if (autoscrollspeed == 0)
- autoscrollspeed = prefs_get_double_attribute_limited ("options.autoscrollspeed", "value", 1, 0, 10);
+ autoscrollspeed = prefs->getDoubleLimited("/options/autoscrollspeed/value", 1, 0, 10);
if (autoscrollspeed != 0)
scroll_world (autoscrollspeed * moved_w);
return false;
}
+bool
+SPDesktop::is_iconified()
+{
+ return 0!=(window_state & GDK_WINDOW_STATE_ICONIFIED);
+}
+
+void
+SPDesktop::iconify()
+{
+ _widget->setIconified();
+}
+
+bool
+SPDesktop::is_maximized()
+{
+ return 0!=(window_state & GDK_WINDOW_STATE_MAXIMIZED);
+}
+
+void
+SPDesktop::maximize()
+{
+ _widget->setMaximized();
+}
+
+bool
+SPDesktop::is_fullscreen()
+{
+ return 0!=(window_state & GDK_WINDOW_STATE_FULLSCREEN);
+}
+
void
SPDesktop::fullscreen()
{
_widget->setFullscreen();
}
+/** \brief Checks to see if the user is working in focused mode
+
+ Returns the value of \c _focusMode
+*/
+bool
+SPDesktop::is_focusMode()
+{
+ return _focusMode;
+}
+
+/** \brief Changes whether the user is in focus mode or not
+ \param mode Which mode the view should be in
+
+*/
+void
+SPDesktop::focusMode (bool mode)
+{
+ if (mode == _focusMode) { return; }
+
+ _focusMode = mode;
+
+ layoutWidget();
+ //sp_desktop_widget_layout(SPDesktopWidget);
+
+ return;
+}
+
void
SPDesktop::getWindowGeometry (gint &x, gint &y, gint &w, gint &h)
{
}
void
-SPDesktop::setWindowPosition (NR::Point p)
+SPDesktop::setWindowPosition (Geom::Point p)
{
_widget->setPosition (p);
}
_widget->setTransient (p, transient_policy);
}
+Gtk::Window*
+SPDesktop::getToplevel( )
+{
+ return _widget->getWindow();
+}
+
void
SPDesktop::presentWindow()
{
return _widget->shutdown();
}
+bool SPDesktop::onDeleteUI (GdkEventAny*)
+{
+ if(shutdown())
+ return true;
+
+ destroyWidget();
+ return false;
+}
+
+/**
+ * onWindowStateEvent
+ *
+ * Called when the window changes its maximize/fullscreen/iconify/pinned state.
+ * Since GTK doesn't have a way to query this state information directly, we
+ * record it for the desktop here, and also possibly trigger a layout.
+ */
+bool
+SPDesktop::onWindowStateEvent (GdkEventWindowState* event)
+{
+ // Record the desktop window's state
+ window_state = event->new_window_state;
+
+ // Layout may differ depending on full-screen mode or not
+ GdkWindowState changed = event->changed_mask;
+ if (changed & (GDK_WINDOW_STATE_FULLSCREEN|GDK_WINDOW_STATE_MAXIMIZED)) {
+ layoutWidget();
+ }
+
+ return false;
+}
+
void
SPDesktop::setToolboxFocusTo (gchar const *label)
{
_widget->setToolboxAdjustmentValue (id, val);
}
+void
+SPDesktop::setToolboxSelectOneValue (gchar const* id, gint val)
+{
+ _widget->setToolboxSelectOneValue (id, val);
+}
+
bool
SPDesktop::isToolboxButtonActive (gchar const *id)
{
void
SPDesktop::emitToolSubselectionChanged(gpointer data)
{
- _tool_subselection_changed.emit(data);
- inkscape_subselection_changed (this);
+ _tool_subselection_changed.emit(data);
+ inkscape_subselection_changed (this);
}
void
SPDesktop::updateNow()
{
- sp_canvas_update_now(canvas);
+ sp_canvas_update_now(canvas);
}
void
GdkCursor *waiting = gdk_cursor_new(GDK_WATCH);
gdk_window_set_cursor(GTK_WIDGET(sp_desktop_canvas(this))->window, waiting);
gdk_cursor_unref(waiting);
+ // GDK needs the flush for the cursor change to take effect
+ gdk_flush();
waiting_cursor = true;
-
- // Stupidly broken GDK cannot just set the new cursor right now - it needs some main loop iterations for that
- // Since setting waiting_cursor is usually immediately followed by some Real Work, we must run the iterations here
- // CAUTION: iterations may redraw, and redraw may be interrupted, so you cannot assume that anything is the same
- // after the call to setWaitingCursor as it was before
- while( Gtk::Main::events_pending() )
- Gtk::Main::iteration();
}
void SPDesktop::clearWaitingCursor()
sp_event_context_update_cursor(sp_desktop_event_context(this));
}
+void SPDesktop::toggleColorProfAdjust()
+{
+ _widget->toggleColorProfAdjust();
+}
+
+void SPDesktop::toggleGrids()
+{
+ if (namedview->grids) {
+ if(gridgroup) {
+ showGrids(!grids_visible);
+ }
+ } else {
+ //there is no grid present at the moment. add a rectangular grid and make it visible
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(namedview);
+ Inkscape::CanvasGrid::writeNewGridToRepr(repr, sp_desktop_document(this), Inkscape::GRID_RECTANGULAR);
+ showGrids(true);
+ }
+}
+
+void SPDesktop::showGrids(bool show, bool dirty_document)
+{
+ grids_visible = show;
+ sp_namedview_show_grids(namedview, grids_visible, dirty_document);
+ if (show) {
+ sp_canvas_item_show(SP_CANVAS_ITEM(gridgroup));
+ } else {
+ sp_canvas_item_hide(SP_CANVAS_ITEM(gridgroup));
+ }
+}
+
+void SPDesktop::toggleSnapGlobal()
+{
+ bool v = namedview->snap_manager.snapprefs.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.
void
SPDesktop::onPositionSet (double x, double y)
{
- _widget->viewSetPosition (NR::Point(x,y));
+ _widget->viewSetPosition (Geom::Point(x,y));
}
void
-SPDesktop::onResized (double x, double y)
+SPDesktop::onResized (double /*x*/, double /*y*/)
{
// Nothing called here
}
/**
* Associate document with desktop.
*/
-/// \todo fixme: refactor SPDesktop::init to use setDocument
void
SPDesktop::setDocument (SPDocument *doc)
{
_commit_connection = doc->connectCommit(sigc::mem_fun(*this, &SPDesktop::updateNow));
/// \todo fixme: This condition exists to make sure the code
- /// inside is called only once on initialization. But there
+ /// inside is NOT called on initialization, only on replacement. But there
/// are surely more safe methods to accomplish this.
+ // TODO since the comment had reversed logic, check the intent of this block of code:
if (drawing) {
- NRArenaItem *ai;
+ NRArenaItem *ai = 0;
namedview = sp_document_namedview (doc, NULL);
_modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this));
SP_ITEM_SHOW_DISPLAY);
if (ai) {
nr_arena_item_add_child (SP_CANVAS_ARENA (drawing)->root, ai, NULL);
- nr_arena_item_unref (ai);
}
namedview->show(this);
/* Ugly hack */
{
_doc2dt[5] = height;
sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (drawing), _doc2dt);
- NR::Rect const a(NR::Point(0, 0), NR::Point(width, height));
+ Geom::Rect const a(Geom::Point(0, 0), Geom::Point(width, height));
SP_CTRLRECT(page)->setRectangle(a);
SP_CTRLRECT(page_border)->setRectangle(a);
}
void
SPDesktop::_onSelectionModified
-(Inkscape::Selection *selection, guint flags, SPDesktop *dt)
+(Inkscape::Selection */*selection*/, guint /*flags*/, SPDesktop *dt)
{
if (!dt->_widget) return;
- dt->_widget->updateScrollbars (expansion(dt->_d2w));
+ dt->_widget->updateScrollbars (dt->_d2w.descrim());
}
static void
* \todo fixme
*/
static gint
-_arena_handler (SPCanvasArena *arena, NRArenaItem *ai, GdkEvent *event, SPDesktop *desktop)
+_arena_handler (SPCanvasArena */*arena*/, NRArenaItem *ai, GdkEvent *event, SPDesktop *desktop)
{
if (ai) {
SPItem *spi = (SPItem*)NR_ARENA_ITEM_GET_DATA (ai);
/// Callback
static void
-_layer_hierarchy_changed(SPObject *top, SPObject *bottom,
+_layer_hierarchy_changed(SPObject */*top*/, SPObject *bottom,
SPDesktop *desktop)
{
desktop->_layer_changed_signal.emit (bottom);
_reconstruction_start (SPDesktop * desktop)
{
// printf("Desktop, starting reconstruction\n");
- desktop->_reconstruction_old_layer_id = g_strdup(SP_OBJECT_ID(desktop->currentLayer()));
+ desktop->_reconstruction_old_layer_id = g_strdup(desktop->currentLayer()->getId());
desktop->_layer_hierarchy->setBottom(desktop->currentRoot());
/*
if (flags & SP_OBJECT_MODIFIED_FLAG) {
- /* Recalculate snap distances */
- /* FIXME: why is the desktop getting involved in setting up something
- ** that is entirely to do with the namedview?
- */
- _update_snap_distances (desktop);
-
/* Show/hide page background */
if (nv->pagecolor & 0xff) {
sp_canvas_item_show (desktop->table);
int order = sp_canvas_item_order (desktop->page_border);
int morder = sp_canvas_item_order (desktop->drawing);
if (morder > order) sp_canvas_item_raise (desktop->page_border,
- morder - order);
+ morder - order);
}
} else {
sp_canvas_item_hide (desktop->page_border);
((CtrlRect *) desktop->page)->setShadow(0, 0x00000000);
}
}
-
+
/* Show/hide page shadow */
if (nv->showpageshadow && nv->pageshadow) {
((CtrlRect *) desktop->page_border)->setShadow(nv->pageshadow, nv->bordercolor);
((CtrlRect *) desktop->page_border)->setShadow(0, 0x00000000);
}
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (SP_RGBA32_A_U(nv->pagecolor) < 128 ||
(SP_RGBA32_R_U(nv->pagecolor) +
SP_RGBA32_G_U(nv->pagecolor) +
SP_RGBA32_B_U(nv->pagecolor)) >= 384) {
// the background color is light or transparent, use black outline
- SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = prefs_get_int_attribute("options.wireframecolors", "onlight", 0xff);
+ SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = prefs->getInt("/options/wireframecolors/onlight", 0xff);
} else { // use white outline
- SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = prefs_get_int_attribute("options.wireframecolors", "ondark", 0xffffffff);
+ SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = prefs->getInt("/options/wireframecolors/ondark", 0xffffffff);
}
}
}
-/**
- * Callback to reset snapper's distances.
- */
-static void
-_update_snap_distances (SPDesktop *desktop)
-{
- SPUnit const &px = sp_unit_get_by_id(SP_UNIT_PX);
-
- SPNamedView &nv = *desktop->namedview;
-
-
- // FIXME GRID: make one gridsnapper object that snaps to all enabled grids by calling their snappers.
- nv.snap_manager.grid.setDistance(sp_convert_distance_full(nv.gridtolerance,
- *nv.gridtoleranceunit,
- px));
- nv.snap_manager.axonomgrid.setDistance(sp_convert_distance_full(nv.gridtolerance,
- *nv.gridtoleranceunit,
- px));
- //new 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,
- *nv.gridtoleranceunit,
- px));
- }
-
- nv.snap_manager.guide.setDistance(sp_convert_distance_full(nv.guidetolerance,
- *nv.guidetoleranceunit,
- px));
- nv.snap_manager.object.setDistance(sp_convert_distance_full(nv.objecttolerance,
- *nv.objecttoleranceunit,
- px));
-}
-
-
-NR::Matrix SPDesktop::w2d() const
+Geom::Matrix SPDesktop::w2d() const
{
return _w2d;
}
-NR::Point SPDesktop::w2d(NR::Point const &p) const
+Geom::Point SPDesktop::w2d(Geom::Point const &p) const
{
return p * _w2d;
}
-NR::Point SPDesktop::d2w(NR::Point const &p) const
+Geom::Point SPDesktop::d2w(Geom::Point const &p) const
{
return p * _d2w;
}
-NR::Matrix SPDesktop::doc2dt() const
+Geom::Matrix SPDesktop::doc2dt() const
{
return _doc2dt;
}
-NR::Point SPDesktop::doc2dt(NR::Point const &p) const
+Geom::Matrix SPDesktop::dt2doc() const
+{
+ // doc2dt is its own inverse
+ return _doc2dt;
+}
+
+Geom::Point SPDesktop::doc2dt(Geom::Point const &p) const
{
return p * _doc2dt;
}
-NR::Point SPDesktop::dt2doc(NR::Point const &p) const
+Geom::Point SPDesktop::dt2doc(Geom::Point const &p) const
{
- return p / _doc2dt;
+ return p * dt2doc();
}
-/**
+/*
* Pop event context from desktop's context stack. Never used.
*/
// void
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :