diff --git a/src/desktop.cpp b/src/desktop.cpp
index 92946cb7dfa5e04e6261452849753f674fb2e441..f7ef1a8cdb79c6d9a02d6a6aef7be6aaf58c5906 100644 (file)
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
#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"
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.
page( 0 ),
page_border( 0 ),
current( 0 ),
+ _focusMode(false),
zooms_past( 0 ),
zooms_future( 0 ),
dkey( 0 ),
_layer_hierarchy( 0 ),
_reconstruction_old_layer_id( 0 ),
_display_mode(Inkscape::RENDERMODE_NORMAL),
- _saved_display_mode(Inkscape::RENDERMODE_NORMAL),
_widget( 0 ),
_inkscape( 0 ),
_guides_message_context( 0 ),
_active( false ),
_w2d(),
_d2w(),
- _doc2dt( NR::Matrix(NR::scale(1, -1)) ),
+ _doc2dt( Geom::Scale(1, -1) ),
grids_visible( false )
{
_d2w.setIdentity();
{
// 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;
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();
}
+ // 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);
- controls = (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 */
/** \todo
* 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()
temporary_item_list = NULL;
}
+ if (selection) {
+ delete selection;
+ selection = NULL;
+ }
+
namedview->hide(this);
_activate_connection.disconnect();
SP_CANVAS_ARENA (drawing)->arena->rendermode = mode;
canvas->rendermode = mode;
_display_mode = mode;
- if (mode != Inkscape::RENDERMODE_OUTLINE) {
- _saved_display_mode = _display_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 (_display_mode == Inkscape::RENDERMODE_OUTLINE) {
- _setDisplayMode(_saved_display_mode);
- } else {
+ 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:
+ default:
+ _setDisplayMode(Inkscape::RENDERMODE_NORMAL);
}
}
bool SPDesktop::isWithinViewport (SPItem *item) const
{
Geom::Rect const viewport = get_display_area();
- boost::optional<NR::Rect> const bbox = sp_item_bbox_desktop(item);
+ Geom::OptRect const bbox = sp_item_bbox_desktop(item);
if (bbox) {
- return viewport.contains(to_2geom(*bbox));
+ return viewport.contains(*bbox);
} else {
return true;
}
g_object_unref (G_OBJECT (ec));
}
- Inkscape::XML::Node *repr = (config) ? inkscape_get_repr (_inkscape, config) : NULL;
- ec = sp_event_context_new (type, this, repr, SP_EVENT_CONTEXT_STATIC);
+ ec = sp_event_context_new (type, this, config, SP_EVENT_CONTEXT_STATIC);
ec->next = event_context;
event_context = ec;
sp_event_context_activate (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;
@@ -635,8 +648,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);
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 ) &&
// FIXME: This 2geom idiom doesn't allow us to declare dbox const
Geom::Rect viewbox = canvas->getViewbox();
- viewbox.expandBy(border);
+ viewbox.expandBy(-border);
double scale = _d2w.descrim();
double newscale;
@@ -767,15 +779,15 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double
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));
+ _d2w = Geom::Scale(newscale, -newscale);
+ _w2d = Geom::Scale(1/newscale, 1/-newscale);
sp_canvas_item_affine_absolute(SP_CANVAS_ITEM(main), _d2w);
clear = TRUE;
}
/* 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;
+ 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);
zooms_future = g_list_remove (zooms_future, ((NRRect *) zooms_future->data));
}
+#include "tools-switch.h"
+#include "node-context.h"
+#include "shape-editor.h"
+#include "nodepath.h"
+
+/** \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;
+
+ if (!zoomed) {
+ SPItem * singleItem = selection->singleItem();
+ if (singleItem != NULL && tools_isactive(this, TOOLS_NODES)) {
+
+ Inkscape::NodePath::Path * nodepath = event_context->shape_editor->get_nodepath();
+ // printf("I've got a nodepath, crazy\n");
+
+ if (nodepath) {
+ Geom::Rect nodes;
+ bool firstnode = true;
+
+ if (nodepath->selected) {
+ for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) {
+ Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data;
+ for (GList *nl = subpath->nodes; nl != NULL; nl = nl->next) {
+ Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data;
+ if (node->selected) {
+ // printf("\tSelected node\n");
+ if (firstnode) {
+ nodes = Geom::Rect(node->pos, node->pos);
+ firstnode = false;
+ } else {
+ nodes.expandTo(node->pos);
+ }
+
+ if (node->p.other != NULL) {
+ /* Include previous node pos */
+ nodes.expandTo(node->p.other->pos);
+
+ /* Include previous handle */
+ if (!sp_node_side_is_line(node, &node->p)) {
+ nodes.expandTo(node->p.pos);
+ }
+ }
+
+ if (node->n.other != NULL) {
+ /* Include previous node pos */
+ nodes.expandTo(node->n.other->pos);
+
+ /* Include previous handle */
+ if (!sp_node_side_is_line(node, &node->n)) {
+ nodes.expandTo(node->n.pos);
+ }
+ }
+ }
+ }
+ }
+
+ if (!firstnode && nodes.area() * 2.0 < _quick_zoom_stored_area.area()) {
+ set_display_area(nodes, 10);
+ 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, 10);
+ 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, 0);
+ }
+
+ _quick_zoom_enabled = enable;
+ return;
+}
+
/**
* Zoom to point with absolute zoom factor.
*/
@@ -872,8 +981,8 @@ SPDesktop::zoom_absolute_keep_point (double cx, double cy, double px, double py,
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,
{
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 = _d2w.descrim() * 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];
+ 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);
}
Geom::Rect d(Geom::Point(0, 0),
Geom::Point(sp_document_width(doc()), sp_document_height(doc())));
- // FIXME: the original NR::Rect::isEmpty call contained an additional threshold of 1.0; is it safe to ignore it?
- if (d.isEmpty()) {
+ if (d.minExtent() < 1.0) {
return;
}
void
SPDesktop::zoom_selection()
{
- boost::optional<Geom::Rect> const d = to_2geom(selection->bounds());
+ Geom::OptRect const d = selection->bounds();
- // FIXME: the original NR::Rect::isEmpty call contained an additional threshold of 0.1; is it safe to ignore it?
- if ( !d || d->isEmpty() ) {
+ if ( !d || d->minExtent() < 0.1 ) {
return;
}
SPItem *docitem = SP_ITEM (sp_document_root (doc()));
g_return_if_fail (docitem != NULL);
- boost::optional<Geom::Rect> d = to_2geom(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.
*/
- // FIXME: the original NR::Rect::isEmpty call contained an additional threshold of 1.0; is it safe to ignore it?
- if ( !d || d->isEmpty() ) {
+ if ( !d || d->minExtent() < 0.1 ) {
return;
}
bool
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 /= _d2w.descrim();
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]) ) {
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];
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);
_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)
{
bool SPDesktop::onDeleteUI (GdkEventAny*)
{
- if(shutdown())
+ if(shutdown())
return true;
destroyWidget();
bool
SPDesktop::onWindowStateEvent (GdkEventWindowState* event)
{
- // Record the desktop window's state
+ // Record the desktop window's state
window_state = event->new_window_state;
// Layout may differ depending on full-screen mode or not
layoutWidget();
}
- return false;
+ return false;
}
void
void
SPDesktop::emitToolSubselectionChanged(gpointer data)
{
- _tool_subselection_changed.emit(data);
- inkscape_subselection_changed (this);
+ _tool_subselection_changed.emit(data);
+ inkscape_subselection_changed (this);
}
void
}
}
-void SPDesktop::toggleSnapping()
+void SPDesktop::toggleSnapGlobal()
{
- bool v = namedview->snap_manager.getSnapEnabledGlobally();
+ bool v = namedview->snap_manager.snapprefs.getSnapEnabledGlobally();
Inkscape::XML::Node *repr = SP_OBJECT_REPR(namedview);
sp_repr_set_boolean(repr, "inkscape:snap-global", !v);
}
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_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;
-
- //tell all grid snappers
- for ( GSList const *l = nv.grids; l != NULL; l = l->next) {
- Inkscape::CanvasGrid *grid = (Inkscape::CanvasGrid*) l->data;
- grid->snapper->setSnapperTolerance(sp_convert_distance_full(nv.gridtolerance,
- *nv.gridtoleranceunit,
- px));
- }
-
- nv.snap_manager.guide.setSnapperTolerance(sp_convert_distance_full(nv.guidetolerance,
- *nv.guidetoleranceunit,
- px));
- nv.snap_manager.object.setSnapperTolerance(sp_convert_distance_full(nv.objecttolerance,
- *nv.objecttoleranceunit,
- px));
-}
-
-
Geom::Matrix SPDesktop::w2d() const
{
return _w2d;
return _doc2dt;
}
+Geom::Matrix SPDesktop::dt2doc() const
+{
+ // doc2dt is its own inverse
+ return _doc2dt;
+}
+
Geom::Point SPDesktop::doc2dt(Geom::Point const &p) const
{
return p * _doc2dt;
Geom::Point SPDesktop::dt2doc(Geom::Point const &p) const
{
- return p * _doc2dt.inverse();
+ return p * dt2doc();
}