static void sp_node_path_value_changed(GtkAdjustment *adj, GObject *tbl, Geom::Dim2 d) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" )); if (!tracker) { return; } Unit const *unit = tracker->getActiveUnit(); if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { prefs->setDouble(Glib::ustring("/tools/nodes/") + (d == Geom::X ? "x" : "y"), Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); } // quit if run by the attr_changed listener if (g_object_get_data( tbl, "freeze" ) || tracker->isUpdating()) { return; } // in turn, prevent listener from responding g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); NodeTool *nt = get_node_tool(); if (nt && !nt->_selected_nodes->empty()) { double val = Quantity::convert(gtk_adjustment_get_value(adj), unit, "px"); double oldval = nt->_selected_nodes->pointwiseBounds()->midpoint()[d]; Geom::Point delta(0,0); delta[d] = val - oldval; nt->_multipath->move(delta); } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); }
static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name, void (SPRect::*setter)(gdouble)) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" )); Unit const *unit = tracker->getActiveUnit(); g_return_if_fail(unit != NULL); if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble(Glib::ustring("/tools/shapes/rect/") + value_name, Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); } // quit if run by the attr_changed listener if (g_object_get_data( tbl, "freeze" ) || tracker->isUpdating()) { return; } // in turn, prevent listener from responding g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); bool modmade = false; Inkscape::Selection *selection = desktop->getSelection(); std::vector<SPItem*> itemlist=selection->itemList(); for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ if (SP_IS_RECT(*i)) { if (gtk_adjustment_get_value(adj) != 0) { (SP_RECT(*i)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); } else { (*i)->getRepr()->setAttribute(value_name, NULL); } modmade = true; } } sp_rtb_sensitivize( tbl ); if (modmade) { DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_RECT, _("Change rectangle")); } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); }
static void sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) { if (g_object_get_data(G_OBJECT(spw), "update")) { return; } UnitTracker *tracker = reinterpret_cast<UnitTracker*>(g_object_get_data(G_OBJECT(spw), "tracker")); if ( !tracker || tracker->isUpdating() ) { /* * When only units are being changed, don't treat changes * to adjuster values as object changes. */ return; } g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); SPDesktop *desktop = SP_ACTIVE_DESKTOP; Inkscape::Selection *selection = sp_desktop_selection(desktop); SPDocument *document = sp_desktop_document(desktop); document->ensureUpToDate (); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Geom::OptRect bbox_vis = selection->visualBounds(); Geom::OptRect bbox_geom = selection->geometricBounds(); int prefs_bbox = prefs->getInt("/tools/bounding_box"); SPItem::BBoxType bbox_type = (prefs_bbox == 0)? SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX; Geom::OptRect bbox_user = selection->bounds(bbox_type); if ( !bbox_user ) { g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); return; } gdouble x0 = 0; gdouble y0 = 0; gdouble x1 = 0; gdouble y1 = 0; gdouble xrel = 0; gdouble yrel = 0; SPUnit const &unit = *tracker->getActiveUnit(); GtkAdjustment* a_x = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "X" ) ); GtkAdjustment* a_y = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "Y" ) ); GtkAdjustment* a_w = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "width" ) ); GtkAdjustment* a_h = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "height" ) ); if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) { x0 = sp_units_get_pixels (gtk_adjustment_get_value (a_x), unit); y0 = sp_units_get_pixels (gtk_adjustment_get_value (a_y), unit); x1 = x0 + sp_units_get_pixels (gtk_adjustment_get_value (a_w), unit); xrel = sp_units_get_pixels (gtk_adjustment_get_value (a_w), unit) / bbox_user->dimensions()[Geom::X]; y1 = y0 + sp_units_get_pixels (gtk_adjustment_get_value (a_h), unit); yrel = sp_units_get_pixels (gtk_adjustment_get_value (a_h), unit) / bbox_user->dimensions()[Geom::Y]; } else { double const x0_propn = gtk_adjustment_get_value (a_x) * unit.unittobase; x0 = bbox_user->min()[Geom::X] * x0_propn; double const y0_propn = gtk_adjustment_get_value (a_y) * unit.unittobase; y0 = y0_propn * bbox_user->min()[Geom::Y]; xrel = gtk_adjustment_get_value (a_w) * unit.unittobase; x1 = x0 + xrel * bbox_user->dimensions()[Geom::X]; yrel = gtk_adjustment_get_value (a_h) * unit.unittobase; y1 = y0 + yrel * bbox_user->dimensions()[Geom::Y]; } // Keep proportions if lock is on GtkToggleAction *lock = GTK_TOGGLE_ACTION( g_object_get_data(G_OBJECT(spw), "lock") ); if ( gtk_toggle_action_get_active(lock) ) { if (adj == a_h) { x1 = x0 + yrel * bbox_user->dimensions()[Geom::X]; } else if (adj == a_w) { y1 = y0 + xrel * bbox_user->dimensions()[Geom::Y]; } } // scales and moves, in px double mh = fabs(x0 - bbox_user->min()[Geom::X]); double sh = fabs(x1 - bbox_user->max()[Geom::X]); double mv = fabs(y0 - bbox_user->min()[Geom::Y]); double sv = fabs(y1 - bbox_user->max()[Geom::Y]); // unless the unit is %, convert the scales and moves to the unit if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) { mh = sp_pixels_get_units (mh, unit); sh = sp_pixels_get_units (sh, unit); mv = sp_pixels_get_units (mv, unit); sv = sp_pixels_get_units (sv, unit); } // do the action only if one of the scales/moves is greater than half the last significant // digit in the spinbox (currently spinboxes have 3 fractional digits, so that makes 0.0005). If // the value was changed by the user, the difference will be at least that much; otherwise it's // just rounding difference between the spinbox value and actual value, so no action is // performed char const * const actionkey = ( mh > 5e-4 ? "selector:toolbar:move:horizontal" : sh > 5e-4 ? "selector:toolbar:scale:horizontal" : mv > 5e-4 ? "selector:toolbar:move:vertical" : sv > 5e-4 ? "selector:toolbar:scale:vertical" : NULL ); if (actionkey != NULL) { // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed sp_desktop_canvas(desktop)->forceFullRedrawAfterInterruptions(0); int transform_stroke = prefs->getBool("/options/transform/stroke", true) ? 1 : 0; Geom::Affine scaler; if (bbox_type == SPItem::VISUAL_BBOX) { scaler = get_scale_transform_for_variable_stroke (*bbox_vis, *bbox_geom, transform_stroke, x0, y0, x1, y1); } else { // 1) We could have use the newer get_scale_transform_for_variable_stroke() here, but to avoid regressions // we'll just use the old get_scale_transform_for_uniform_stroke() for now. // 2) get_scale_transform_for_uniform_stroke() is intended for visual bounding boxes, not geometrical ones! // we'll trick it into using a geometric bounding box though, by setting the stroke width to zero scaler = get_scale_transform_for_uniform_stroke (*bbox_geom, 0, false, x0, y0, x1, y1); } sp_selection_apply_affine(selection, scaler); DocumentUndo::maybeDone(document, actionkey, SP_VERB_CONTEXT_SELECT, _("Transform by toolbar")); // resume interruptibility sp_desktop_canvas(desktop)->endForcedFullRedraws(); } g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); }