X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fwidgets%2Fselect-toolbar.cpp;h=09f8c35f9a822fa212f3674e0bf4d2cb871887e1;hb=0a81f52d29547519319ed7374d2df4ff72eaa4d9;hp=4230c7adb55307ed46803851e6c1f8d9867cfd2b;hpb=6b15695578f07a3f72c4c9475c1a261a3021472a;p=inkscape.git diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index 4230c7adb..09f8c35f9 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -4,6 +4,7 @@ * Authors: * Lauris Kaplinski * bulia byak + * Jon A. Cruz * * Copyright (C) 2003-2005 authors * @@ -15,11 +16,14 @@ #endif #include +#include #include "widgets/button.h" #include "widgets/spw-utilities.h" #include "widgets/widget-sizes.h" #include "widgets/spinbutton-events.h" +#include "widgets/icon.h" +#include "widgets/sp-widget.h" #include "prefs-utils.h" #include "selection-chemistry.h" @@ -31,10 +35,8 @@ #include "sp-namedview.h" #include "toolbox.h" #include -#include "widgets/sp-widget.h" #include "helper/unit-menu.h" #include "helper/units.h" -#include "widgets/sp-widget.h" #include "inkscape.h" #include "verbs.h" #include "prefs-utils.h" @@ -42,57 +44,67 @@ #include "selection-chemistry.h" #include "sp-item-transform.h" #include "message-stack.h" +#include "display/sp-canvas.h" +#include "helper/unit-tracker.h" +#include "ege-adjustment-action.h" +#include "ege-output-action.h" +#include "ink-action.h" +using Inkscape::UnitTracker; static void sp_selection_layout_widget_update(SPWidget *spw, Inkscape::Selection *sel) { - if (gtk_object_get_data(GTK_OBJECT(spw), "update")) { + if (g_object_get_data(G_OBJECT(spw), "update")) { return; } - gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); - - GtkWidget *f = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(spw), "frame"); + g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); + bool setActive = false; using NR::X; using NR::Y; if ( sel && !sel->isEmpty() ) { - NR::Rect const bbox(sel->bounds()); - NR::Point const dimensions(bbox.dimensions()); - if ((dimensions[X] > 1e-6) || (dimensions[Y] > 1e-6)) { - GtkWidget *us = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(spw), "units"); - SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(us)); + NR::Maybe const bbox(sel->bounds()); + if ( bbox && !bbox->isEmpty() ) { + UnitTracker *tracker = reinterpret_cast(g_object_get_data(G_OBJECT(spw), "tracker")); + SPUnit const &unit = *tracker->getActiveUnit(); + + struct { char const *key; double val; } const keyval[] = { + { "X", bbox->min()[X] }, + { "Y", bbox->min()[Y] }, + { "width", bbox->extent(X) }, + { "height", bbox->extent(Y) } + }; if (unit.base == SP_UNIT_DIMENSIONLESS) { - char const * const keys[] = {"X", "Y", "width", "height"}; double const val = 1. / unit.unittobase; - for (unsigned i = 0; i < G_N_ELEMENTS(keys); ++i) { - GtkAdjustment *a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), keys[i]); + for (unsigned i = 0; i < G_N_ELEMENTS(keyval); ++i) { + GtkAdjustment *a = (GtkAdjustment *) g_object_get_data(G_OBJECT(spw), keyval[i].key); gtk_adjustment_set_value(a, val); + tracker->setFullVal( a, keyval[i].val ); } } else { - struct { char const *key; double val; } const keyval[] = { - { "X", bbox.min()[X] }, - { "Y", bbox.min()[Y] }, - { "width", dimensions[X] }, - { "height", dimensions[Y] } - }; for (unsigned i = 0; i < G_N_ELEMENTS(keyval); ++i) { - GtkAdjustment *a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), keyval[i].key); + GtkAdjustment *a = (GtkAdjustment *) g_object_get_data(G_OBJECT(spw), keyval[i].key); gtk_adjustment_set_value(a, sp_pixels_get_units(keyval[i].val, unit)); } } - gtk_widget_set_sensitive(f, TRUE); + setActive = true; } else { - gtk_widget_set_sensitive(f, FALSE); + setActive = false; } } else { - gtk_widget_set_sensitive(f, FALSE); + setActive = false; + } + + GtkActionGroup *selectionActions = GTK_ACTION_GROUP( g_object_get_data(G_OBJECT(spw), "selectionActions") ); + if ( selectionActions ) { +// gtk_action_group_set_sensitive( selectionActions, setActive ); } - gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); + g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); } @@ -100,7 +112,7 @@ static void sp_selection_layout_widget_modify_selection(SPWidget *spw, Inkscape::Selection *selection, guint flags, gpointer data) { SPDesktop *desktop = (SPDesktop *) data; - if ((SP_DT_SELECTION(desktop) == selection) // only respond to changes in our desktop + if ((sp_desktop_selection(desktop) == selection) // only respond to changes in our desktop && (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG ))) @@ -113,86 +125,85 @@ static void sp_selection_layout_widget_change_selection(SPWidget *spw, Inkscape::Selection *selection, gpointer data) { SPDesktop *desktop = (SPDesktop *) data; - if (SP_DT_SELECTION(desktop) == selection) // only respond to changes in our desktop + if (sp_desktop_selection(desktop) == selection) // only respond to changes in our desktop sp_selection_layout_widget_update(spw, selection); } static void sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) { - if (gtk_object_get_data(GTK_OBJECT(spw), "update")) { + if (g_object_get_data(G_OBJECT(spw), "update")) { return; } - GtkWidget *us = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(spw), "units"); - SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(us)); - if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(us))) { + UnitTracker *tracker = reinterpret_cast(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; } - gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); + g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); - SPDocument *document = SP_DT_DOCUMENT(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); + SPDocument *document = sp_desktop_document(desktop); sp_document_ensure_up_to_date (document); - NR::Rect bbox = selection->bounds(); + NR::Maybe bbox = selection->bounds(); - if (!((bbox.max()[NR::X] - bbox.min()[NR::X] > 1e-6) || (bbox.max()[NR::Y] - bbox.min()[NR::Y] > 1e-6))) { + if ( !bbox || bbox->isEmpty() ) { + g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); return; } - gdouble x0, y0, x1, y1, xrel, yrel; - GtkAdjustment *a_w; - GtkAdjustment *a_h; + 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) { - GtkAdjustment *a; - a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "X"); - x0 = sp_units_get_pixels (a->value, unit); - a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "Y"); - y0 = sp_units_get_pixels (a->value, unit); - a_w = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "width"); + x0 = sp_units_get_pixels (a_x->value, unit); + y0 = sp_units_get_pixels (a_y->value, unit); x1 = x0 + sp_units_get_pixels (a_w->value, unit); - xrel = sp_units_get_pixels (a_w->value, unit) / bbox.extent(NR::X); - a_h = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "height"); + xrel = sp_units_get_pixels (a_w->value, unit) / bbox->extent(NR::X); y1 = y0 + sp_units_get_pixels (a_h->value, unit); - yrel = sp_units_get_pixels (a_h->value, unit) / bbox.extent(NR::Y); + yrel = sp_units_get_pixels (a_h->value, unit) / bbox->extent(NR::Y); } else { - GtkAdjustment *a; - a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "X"); - double const x0_propn = a->value * unit.unittobase; - x0 = bbox.min()[NR::X] * x0_propn; - a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "Y"); - double const y0_propn = a->value * unit.unittobase; - y0 = y0_propn * bbox.min()[NR::Y]; - a_w = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "width"); + double const x0_propn = a_x->value * unit.unittobase; + x0 = bbox->min()[NR::X] * x0_propn; + double const y0_propn = a_y->value * unit.unittobase; + y0 = y0_propn * bbox->min()[NR::Y]; xrel = a_w->value * unit.unittobase; - x1 = x0 + xrel * bbox.extent(NR::X); - a_h = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "height"); + x1 = x0 + xrel * bbox->extent(NR::X); yrel = a_h->value * unit.unittobase; - y1 = y0 + yrel * bbox.extent(NR::Y); + y1 = y0 + yrel * bbox->extent(NR::Y); } // Keep proportions if lock is on - GtkWidget *lock = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(spw), "lock")); - if (SP_BUTTON_IS_DOWN(lock)) { + 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.extent(NR::X); + x1 = x0 + yrel * bbox->extent(NR::X); } else if (adj == a_w) { - y1 = y0 + xrel * bbox.extent(NR::Y); + y1 = y0 + xrel * bbox->extent(NR::Y); } } // scales and moves, in px - double mh = fabs(x0 - bbox.min()[NR::X]); - double sh = fabs(x1 - bbox.max()[NR::X]); - double mv = fabs(y0 - bbox.min()[NR::Y]); - double sv = fabs(y1 - bbox.max()[NR::Y]); + double mh = fabs(x0 - bbox->min()[NR::X]); + double sh = fabs(x1 - bbox->max()[NR::X]); + double mv = fabs(y0 - bbox->min()[NR::Y]); + double sv = fabs(y1 - bbox->max()[NR::Y]); // unless the unit is %, convert the scales and moves to the unit if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) { @@ -207,324 +218,321 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) // 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" : + 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_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0); + gdouble strokewidth = stroke_average_width (selection->itemList()); int transform_stroke = prefs_get_int_attribute ("options.transform", "stroke", 1); - NR::Matrix scaler = get_scale_transform_with_stroke (bbox, strokewidth, transform_stroke, x0, y0, x1, y1); + NR::Matrix scaler = get_scale_transform_with_stroke (*bbox, strokewidth, transform_stroke, x0, y0, x1, y1); sp_selection_apply_affine(selection, scaler); - sp_document_maybe_done (document, actionkey); + sp_document_maybe_done (document, actionkey, SP_VERB_CONTEXT_SELECT, + _("Transform by toolbar")); - // defocus spinbuttons by moving focus to the canvas, unless "stay" is on - spinbutton_defocus(GTK_OBJECT(spw)); + // resume interruptibility + sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop)); } - gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); + g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); } -GtkWidget * -sp_select_toolbox_spinbutton(gchar *label, gchar *data, float lower_limit, GtkWidget *us, GtkWidget *spw, gchar *tooltip, gboolean altx) +static EgeAdjustmentAction * create_adjustment_action( gchar const *name, + gchar const *label, + gchar const *shortLabel, + gchar const *data, + gdouble lower, + GtkWidget* focusTarget, + UnitTracker* tracker, + GtkWidget* spw, + gchar const *tooltip, + gboolean altx ) { - GtkTooltips *tt = gtk_tooltips_new(); - - GtkWidget *hb = gtk_hbox_new(FALSE, 1); - GtkWidget *l = gtk_label_new(Q_(label)); - gtk_tooltips_set_tip(tt, l, tooltip, NULL); - gtk_widget_show(l); - gtk_misc_set_alignment(GTK_MISC(l), 1.0, 0.5); - gtk_container_add(GTK_CONTAINER(hb), l); - - GtkObject *a = gtk_adjustment_new(0.0, lower_limit, 1e6, SPIN_STEP, SPIN_PAGE_STEP, SPIN_PAGE_STEP); - sp_unit_selector_add_adjustment(SP_UNIT_SELECTOR(us), GTK_ADJUSTMENT(a)); - gtk_object_set_data(GTK_OBJECT(spw), data, a); - - GtkWidget *sb = gtk_spin_button_new(GTK_ADJUSTMENT(a), SPIN_STEP, 3); - gtk_tooltips_set_tip(tt, sb, tooltip, NULL); - gtk_widget_set_size_request(sb, AUX_SPINBUTTON_WIDTH, AUX_SPINBUTTON_HEIGHT); - gtk_widget_show(sb); - gtk_signal_connect(GTK_OBJECT(sb), "focus-in-event", GTK_SIGNAL_FUNC(spinbutton_focus_in), spw); - gtk_signal_connect(GTK_OBJECT(sb), "key-press-event", GTK_SIGNAL_FUNC(spinbutton_keypress), spw); - - gtk_container_add(GTK_CONTAINER(hb), sb); - gtk_signal_connect(GTK_OBJECT(a), "value_changed", GTK_SIGNAL_FUNC(sp_object_layout_any_value_changed), spw); - - if (altx) { // this spinbutton will be activated by alt-x - gtk_object_set_data(GTK_OBJECT(sb), "altx", sb); + GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0.0, lower, 1e6, SPIN_STEP, SPIN_PAGE_STEP, SPIN_PAGE_STEP ) ); + if (tracker) { + tracker->addAdjustment(adj); } - - return hb; -} - -static gboolean aux_set_unit(SPUnitSelector *, - SPUnit const *old, - SPUnit const *new_units, - GObject *dlg) -{ - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - - if (!desktop) { - return FALSE; + if ( spw ) { + g_object_set_data( G_OBJECT(spw), data, adj ); } - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); - - if (selection->isEmpty()) - return FALSE; - - if ((old->base == SP_UNIT_ABSOLUTE || old->base == SP_UNIT_DEVICE) - && (new_units->base == SP_UNIT_DIMENSIONLESS)) - { - - /* Absolute to percentage */ - g_object_set_data(dlg, "update", GUINT_TO_POINTER(TRUE)); - - GtkAdjustment *ax = GTK_ADJUSTMENT(g_object_get_data(dlg, "X")); - GtkAdjustment *ay = GTK_ADJUSTMENT(g_object_get_data(dlg, "Y")); - GtkAdjustment *aw = GTK_ADJUSTMENT(g_object_get_data(dlg, "width")); - GtkAdjustment *ah = GTK_ADJUSTMENT(g_object_get_data(dlg, "height")); - - double const x = sp_units_get_pixels (ax->value, *old); - double const y = sp_units_get_pixels (ay->value, *old); - double const w = sp_units_get_pixels (aw->value, *old); - double const h = sp_units_get_pixels (ah->value, *old); - - NR::Rect bbox = selection->bounds(); - - gtk_adjustment_set_value(ax, fabs(bbox.min()[NR::X]) > 1e-6? 100.0 * x / bbox.min()[NR::X] : 100.0); - gtk_adjustment_set_value(ay, fabs(bbox.min()[NR::Y]) > 1e-6? 100.0 * y / bbox.min()[NR::Y] : 100.0); - gtk_adjustment_set_value(aw, fabs(bbox.extent(NR::X)) > 1e-6? 100.0 * w / bbox.extent(NR::X) : 100.0); - gtk_adjustment_set_value(ah, fabs(bbox.extent(NR::Y)) > 1e-6? 100.0 * h / bbox.extent(NR::Y) : 100.0); - - g_object_set_data(dlg, "update", GUINT_TO_POINTER(FALSE)); - return TRUE; - } else if ((old->base == SP_UNIT_DIMENSIONLESS) - && (new_units->base == SP_UNIT_ABSOLUTE || new_units->base == SP_UNIT_DEVICE)) { - - /* Percentage to absolute */ - g_object_set_data(dlg, "update", GUINT_TO_POINTER(TRUE)); - - GtkAdjustment *ax = GTK_ADJUSTMENT(g_object_get_data(dlg, "X")); - GtkAdjustment *ay = GTK_ADJUSTMENT(g_object_get_data(dlg, "Y")); - GtkAdjustment *aw = GTK_ADJUSTMENT(g_object_get_data(dlg, "width")); - GtkAdjustment *ah = GTK_ADJUSTMENT(g_object_get_data(dlg, "height")); - - NR::Rect bbox = selection->bounds(); + EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, Q_(label), tooltip, 0, SPIN_STEP, 3 ); + if ( shortLabel ) { + g_object_set( act, "short_label", Q_(shortLabel), NULL ); + } - gtk_adjustment_set_value(ax, sp_pixels_get_units(0.01 * ax->value * bbox.min()[NR::X], *new_units)); - gtk_adjustment_set_value(ay, sp_pixels_get_units(0.01 * ay->value * bbox.min()[NR::Y], *new_units)); - gtk_adjustment_set_value(aw, sp_pixels_get_units(0.01 * aw->value * bbox.extent(NR::X), *new_units)); - gtk_adjustment_set_value(ah, sp_pixels_get_units(0.01 * ah->value * bbox.extent(NR::Y), *new_units)); + gtk_signal_connect( GTK_OBJECT(adj), "value_changed", GTK_SIGNAL_FUNC(sp_object_layout_any_value_changed), spw ); + if ( focusTarget ) { + ege_adjustment_action_set_focuswidget( act, focusTarget ); + } - g_object_set_data(dlg, "update", GUINT_TO_POINTER(FALSE)); - return TRUE; + if ( altx ) { // this spinbutton will be activated by alt-x + g_object_set( G_OBJECT(act), "self-id", "altx", NULL ); } - return FALSE; + // Using a cast just to make sure we pass in the right kind of function pointer + g_object_set( G_OBJECT(act), "tool-post", static_cast(sp_set_font_size_smaller), NULL ); + + return act; } // toggle button callbacks and updaters -static void toggle_stroke (GtkWidget *button, gpointer data) { - prefs_set_int_attribute ("options.transform", "stroke", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ? 1 : 0); +static void toggle_stroke( GtkToggleAction* act, gpointer data ) { + gboolean active = gtk_toggle_action_get_active( act ); + prefs_set_int_attribute( "options.transform", "stroke", active ? 1 : 0 ); SPDesktop *desktop = (SPDesktop *)data; - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) { + if ( active ) { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now stroke width is scaled when objects are scaled.")); } else { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now stroke width is not scaled when objects are scaled.")); } } -static void toggle_corners (GtkWidget *button, gpointer data) { - prefs_set_int_attribute ("options.transform", "rectcorners", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ? 1 : 0); +static void toggle_corners( GtkToggleAction* act, gpointer data) { + gboolean active = gtk_toggle_action_get_active( act ); + prefs_set_int_attribute( "options.transform", "rectcorners", active ? 1 : 0 ); SPDesktop *desktop = (SPDesktop *)data; - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) { + if ( active ) { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now rounded rectangle corners are scaled when rectangles are scaled.")); } else { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now rounded rectangle corners are not scaled when rectangles are scaled.")); } } -static void toggle_gradient (GtkWidget *button, gpointer data) { - prefs_set_int_attribute ("options.transform", "gradient", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ? 1 : 0); +static void toggle_gradient( GtkToggleAction *act, gpointer data ) { + gboolean active = gtk_toggle_action_get_active( act ); + prefs_set_int_attribute( "options.transform", "gradient", active ? 1 : 0 ); SPDesktop *desktop = (SPDesktop *)data; - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) { + if ( active ) { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now gradients are transformed along with their objects when those are transformed (moved, scaled, rotated, or skewed).")); } else { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now gradients remain fixed when objects are transformed (moved, scaled, rotated, or skewed).")); } } -static void toggle_pattern (GtkWidget *button, gpointer data) { - prefs_set_int_attribute ("options.transform", "pattern", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) ? 1 : 0); +static void toggle_pattern( GtkToggleAction* act, gpointer data ) { + gboolean active = gtk_toggle_action_get_active( act ); + prefs_set_int_attribute( "options.transform", "pattern", active ? 1 : 0 ); SPDesktop *desktop = (SPDesktop *)data; - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) { + if ( active ) { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now patterns are transformed along with their objects when those are transformed (moved, scaled, rotated, or skewed).")); } else { desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now patterns remain fixed when objects are transformed (moved, scaled, rotated, or skewed).")); } } -GtkWidget * -sp_select_toolbox_new(SPDesktop *desktop) +static void toggle_lock( GtkToggleAction *act, gpointer /*data*/ ) { + gboolean active = gtk_toggle_action_get_active( act ); + if ( active ) { + g_object_set( G_OBJECT(act), "iconId", "width_height_lock", NULL ); + } else { + g_object_set( G_OBJECT(act), "iconId", "lock_unlocked", NULL ); + } +} + +static void destroy_tracker( GObject* obj, gpointer /*user_data*/ ) { - Inkscape::UI::View::View *view = desktop; + UnitTracker *tracker = reinterpret_cast(g_object_get_data(obj, "tracker")); + if ( tracker ) { + delete tracker; + g_object_set_data( obj, "tracker", 0 ); + } +} - GtkTooltips *tt = gtk_tooltips_new(); - GtkWidget *tb = gtk_hbox_new(FALSE, 0); +static void trigger_sp_action( GtkAction* /*act*/, gpointer user_data ) +{ + SPAction* targetAction = SP_ACTION(user_data); + if ( targetAction ) { + sp_action_perform( targetAction, NULL ); + } +} - sp_toolbox_button_normal_new_from_verb(tb, GTK_ICON_SIZE_SMALL_TOOLBAR, Inkscape::Verb::get(SP_VERB_OBJECT_ROTATE_90_CCW), view, tt); - sp_toolbox_button_normal_new_from_verb(tb, GTK_ICON_SIZE_SMALL_TOOLBAR, Inkscape::Verb::get(SP_VERB_OBJECT_ROTATE_90_CW), view, tt); - sp_toolbox_button_normal_new_from_verb(tb, GTK_ICON_SIZE_SMALL_TOOLBAR, Inkscape::Verb::get(SP_VERB_OBJECT_FLIP_HORIZONTAL), view, tt); - sp_toolbox_button_normal_new_from_verb(tb, GTK_ICON_SIZE_SMALL_TOOLBAR, Inkscape::Verb::get(SP_VERB_OBJECT_FLIP_VERTICAL), view, tt); +static GtkAction* create_action_for_verb( Inkscape::Verb* verb, Inkscape::UI::View::View* view, Inkscape::IconSize size ) +{ + GtkAction* act = 0; - aux_toolbox_space(tb, AUX_BETWEEN_BUTTON_GROUPS); + SPAction* targetAction = verb->get_action(view); + InkAction* inky = ink_action_new( verb->get_id(), verb->get_name(), verb->get_tip(), verb->get_image(), size ); + act = GTK_ACTION(inky); - sp_toolbox_button_normal_new_from_verb(tb, GTK_ICON_SIZE_SMALL_TOOLBAR, Inkscape::Verb::get(SP_VERB_SELECTION_TO_BACK), view, tt); - sp_toolbox_button_normal_new_from_verb(tb, GTK_ICON_SIZE_SMALL_TOOLBAR, Inkscape::Verb::get(SP_VERB_SELECTION_LOWER), view, tt); - sp_toolbox_button_normal_new_from_verb(tb, GTK_ICON_SIZE_SMALL_TOOLBAR, Inkscape::Verb::get(SP_VERB_SELECTION_RAISE), view, tt); - sp_toolbox_button_normal_new_from_verb(tb, GTK_ICON_SIZE_SMALL_TOOLBAR, Inkscape::Verb::get(SP_VERB_SELECTION_TO_FRONT), view, tt); + g_signal_connect( G_OBJECT(inky), "activate", GTK_SIGNAL_FUNC(trigger_sp_action), targetAction ); + + return act; +} + +void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + Inkscape::UI::View::View *view = desktop; + + GtkAction* act = 0; + + GtkActionGroup* selectionActions = mainActions; // temporary + + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_EDIT_SELECT_ALL), view, Inkscape::ICON_SIZE_SMALL_TOOLBAR ); + gtk_action_group_add_action( selectionActions, act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_EDIT_SELECT_ALL_IN_ALL_LAYERS), view, Inkscape::ICON_SIZE_SMALL_TOOLBAR ); + gtk_action_group_add_action( selectionActions, act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_EDIT_DESELECT), view, Inkscape::ICON_SIZE_SMALL_TOOLBAR ); + gtk_action_group_add_action( selectionActions, act ); + + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_OBJECT_ROTATE_90_CCW), view, Inkscape::ICON_SIZE_SMALL_TOOLBAR ); + gtk_action_group_add_action( selectionActions, act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_OBJECT_ROTATE_90_CW), view, Inkscape::ICON_SIZE_SMALL_TOOLBAR ); + gtk_action_group_add_action( selectionActions, act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_OBJECT_FLIP_HORIZONTAL), view, Inkscape::ICON_SIZE_SMALL_TOOLBAR ); + gtk_action_group_add_action( selectionActions, act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_OBJECT_FLIP_VERTICAL), view, Inkscape::ICON_SIZE_SMALL_TOOLBAR ); + gtk_action_group_add_action( selectionActions, act ); + + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_SELECTION_TO_BACK), view, Inkscape::ICON_SIZE_SMALL_TOOLBAR ); + gtk_action_group_add_action( selectionActions, act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_SELECTION_LOWER), view, Inkscape::ICON_SIZE_SMALL_TOOLBAR ); + gtk_action_group_add_action( selectionActions, act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_SELECTION_RAISE), view, Inkscape::ICON_SIZE_SMALL_TOOLBAR ); + gtk_action_group_add_action( selectionActions, act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_SELECTION_TO_FRONT), view, Inkscape::ICON_SIZE_SMALL_TOOLBAR ); + gtk_action_group_add_action( selectionActions, act ); // Create the parent widget for x y w h tracker. GtkWidget *spw = sp_widget_new_global(INKSCAPE); // Remember the desktop's canvas widget, to be used for defocusing. - gtk_object_set_data(GTK_OBJECT(spw), "dtw", SP_DT_CANVAS(desktop)); + g_object_set_data(G_OBJECT(spw), "dtw", sp_desktop_canvas(desktop)); // The vb frame holds all other widgets and is used to set sensitivity depending on selection state. GtkWidget *vb = gtk_hbox_new(FALSE, 0); gtk_widget_show(vb); gtk_container_add(GTK_CONTAINER(spw), vb); - gtk_object_set_data(GTK_OBJECT(spw), "frame", vb); // Create the units menu. - GtkWidget *us = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); - sp_unit_selector_setsize(us, AUX_OPTION_MENU_WIDTH, AUX_OPTION_MENU_HEIGHT); - sp_unit_selector_add_unit(SP_UNIT_SELECTOR(us), &sp_unit_get_by_id(SP_UNIT_PERCENT), 0); - sp_unit_selector_set_unit (SP_UNIT_SELECTOR(us), SP_DT_NAMEDVIEW(desktop)->doc_units); - g_signal_connect(G_OBJECT(us), "set_unit", G_CALLBACK(aux_set_unit), spw); + UnitTracker* tracker = new UnitTracker( SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE ); + tracker->addUnit( SP_UNIT_PERCENT, 0 ); + tracker->setActiveUnit( sp_desktop_namedview(desktop)->doc_units ); + + g_object_set_data( G_OBJECT(spw), "tracker", tracker ); + g_signal_connect( G_OBJECT(spw), "destroy", G_CALLBACK(destroy_tracker), spw ); + + EgeAdjustmentAction* eact = 0; // four spinbuttons - gtk_container_add(GTK_CONTAINER(vb), - //TRANSLATORS: only translate "string" in "context|string". - // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS - sp_select_toolbox_spinbutton(_("select_toolbar|X"), "X", -1e6, us, spw, _("Horizontal coordinate of selection"), TRUE)); - aux_toolbox_space(vb, AUX_BETWEEN_SPINBUTTONS); - gtk_container_add(GTK_CONTAINER(vb), - //TRANSLATORS: only translate "string" in "context|string". - // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS - sp_select_toolbox_spinbutton(_("select_toolbar|Y"), "Y", -1e6, us, spw, _("Vertical coordinate of selection"), FALSE)); - aux_toolbox_space(vb, AUX_BETWEEN_BUTTON_GROUPS); - - gtk_container_add(GTK_CONTAINER(vb), - //TRANSLATORS: only translate "string" in "context|string". - // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS - sp_select_toolbox_spinbutton(_("select_toolbar|W"), "width", 1e-3, us, spw, _("Width of selection"), FALSE)); + //TRANSLATORS: only translate "string" in "context|string". + // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS + eact = create_adjustment_action( "XAction", _("select_toolbar|X position"), _("select_toolbar|X"), "X", + -1e6, GTK_WIDGET(desktop->canvas), tracker, spw, + _("Horizontal coordinate of selection"), TRUE ); + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); + + //TRANSLATORS: only translate "string" in "context|string". + // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS + eact = create_adjustment_action( "YAction", _("select_toolbar|Y position"), _("select_toolbar|Y"), "Y", + -1e6, GTK_WIDGET(desktop->canvas), tracker, spw, + _("Vertical coordinate of selection"), FALSE ); + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); + + //TRANSLATORS: only translate "string" in "context|string". + // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS + eact = create_adjustment_action( "WidthAction", _("select_toolbar|Width"), _("select_toolbar|W"), "width", + 1e-3, GTK_WIDGET(desktop->canvas), tracker, spw, + _("Width of selection"), FALSE ); + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); // lock toggle - GtkWidget *lockbox = gtk_vbox_new(TRUE, 0); - GtkWidget *lock = sp_button_new_from_data( GTK_ICON_SIZE_MENU, - SP_BUTTON_TYPE_TOGGLE, - NULL, - "width_height_lock", - _("Change both width and height by the same proportion"), - tt); - gtk_box_pack_start(GTK_BOX(lockbox), lock, TRUE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(vb), lockbox, FALSE, FALSE, 0); - gtk_object_set_data(GTK_OBJECT(spw), "lock", lock); - - gtk_container_add(GTK_CONTAINER(vb), - //TRANSLATORS: only translate "string" in "context|string". - // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS - sp_select_toolbox_spinbutton(_("select_toolbar|H"), "height", 1e-3, us, spw, _("Height of selection"), FALSE)); - - aux_toolbox_space(vb, 2); + { + InkToggleAction* itact = ink_toggle_action_new( "LockAction", + _("Lock width and height"), + _("When locked, change both width and height by the same proportion"), + "lock_unlocked", + Inkscape::ICON_SIZE_DECORATION ); + g_object_set( itact, "short_label", "Lock", NULL ); + g_object_set_data( G_OBJECT(spw), "lock", itact ); + g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_lock), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); + } + + //TRANSLATORS: only translate "string" in "context|string". + // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS + eact = create_adjustment_action( "HeightAction", _("select_toolbar|Height"), _("select_toolbar|H"), "height", + 1e-3, GTK_WIDGET(desktop->canvas), tracker, spw, + _("Height of selection"), FALSE ); + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); // Add the units menu. - gtk_widget_show(us); - gtk_container_add(GTK_CONTAINER(vb), us); - gtk_object_set_data(GTK_OBJECT(spw), "units", us); + act = tracker->createAction( "UnitsAction", _("Units"), ("") ); + gtk_action_group_add_action( selectionActions, act ); - // Set font size. - sp_set_font_size_smaller (vb); + g_object_set_data( G_OBJECT(spw), "selectionActions", selectionActions ); // Force update when selection changes. gtk_signal_connect(GTK_OBJECT(spw), "modify_selection", GTK_SIGNAL_FUNC(sp_selection_layout_widget_modify_selection), desktop); gtk_signal_connect(GTK_OBJECT(spw), "change_selection", GTK_SIGNAL_FUNC(sp_selection_layout_widget_change_selection), desktop); // Update now. - sp_selection_layout_widget_update(SP_WIDGET(spw), SP_ACTIVE_DESKTOP ? SP_DT_SELECTION(SP_ACTIVE_DESKTOP) : NULL); + sp_selection_layout_widget_update(SP_WIDGET(spw), SP_ACTIVE_DESKTOP ? sp_desktop_selection(SP_ACTIVE_DESKTOP) : NULL); // Insert spw into the toolbar. - gtk_box_pack_start(GTK_BOX(tb), spw, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS); - - aux_toolbox_space(tb, AUX_BETWEEN_BUTTON_GROUPS); + gtk_box_pack_start(GTK_BOX(holder), spw, FALSE, FALSE, 0); // "Transform with object" buttons - GtkWidget *cvbox = gtk_vbox_new (FALSE, 0); - GtkWidget *cbox = gtk_hbox_new (FALSE, 0); - { - GtkWidget *button = sp_button_new_from_data( GTK_ICON_SIZE_SMALL_TOOLBAR, - SP_BUTTON_TYPE_TOGGLE, - NULL, - "transform_stroke", - _("When scaling objects, scale the stroke width by the same proportion"), - tt); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), prefs_get_int_attribute ("options.transform", "stroke", 1)); - g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (toggle_stroke), desktop); - gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0); + EgeOutputAction* act = ege_output_action_new( "transform_affect_label", _("Affect:"), "", 0 ); + ege_output_action_set_use_markup( act, TRUE ); + g_object_set( act, "visible-overflown", FALSE, NULL ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); } { - GtkWidget *button = sp_button_new_from_data( GTK_ICON_SIZE_SMALL_TOOLBAR, - SP_BUTTON_TYPE_TOGGLE, - NULL, - "transform_corners", - _("When scaling rectangles, scale the radii of rounded corners"), - tt); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), prefs_get_int_attribute ("options.transform", "rectcorners", 1)); - g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (toggle_corners), desktop); - gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0); + InkToggleAction* itact = ink_toggle_action_new( "transform_stroke", + _("Scale stroke width"), + _("When scaling objects, scale the stroke width by the same proportion"), + "transform_stroke", + Inkscape::ICON_SIZE_DECORATION ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs_get_int_attribute("options.transform", "stroke", 1) ); + g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_stroke), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); } { - GtkWidget *button = sp_button_new_from_data( GTK_ICON_SIZE_SMALL_TOOLBAR, - SP_BUTTON_TYPE_TOGGLE, - NULL, - "transform_gradient", - _("Transform gradients (in fill or stroke) along with the objects"), - tt); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), prefs_get_int_attribute ("options.transform", "gradient", 1)); - g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (toggle_gradient), desktop); - gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0); + InkToggleAction* itact = ink_toggle_action_new( "transform_corners", + _("Scale rounded corners"), + _("When scaling rectangles, scale the radii of rounded corners"), + "transform_corners", + Inkscape::ICON_SIZE_DECORATION ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs_get_int_attribute("options.transform", "rectcorners", 1) ); + g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_corners), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); } { - GtkWidget *button = sp_button_new_from_data( GTK_ICON_SIZE_SMALL_TOOLBAR, - SP_BUTTON_TYPE_TOGGLE, - NULL, - "transform_pattern", - _("Transform patterns (in fill or stroke) along with the objects"), - tt); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), prefs_get_int_attribute ("options.transform", "pattern", 1)); - g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (toggle_pattern), desktop); - gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0); + InkToggleAction* itact = ink_toggle_action_new( "transform_gradient", + _("Move gradients"), + _("Move gradients (in fill or stroke) along with the objects"), + "transform_gradient", + Inkscape::ICON_SIZE_DECORATION ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs_get_int_attribute("options.transform", "gradient", 1) ); + g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_gradient), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); } - gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(tb), cvbox, FALSE, FALSE, 0); - - gtk_widget_show_all(tb); - - return tb; + { + InkToggleAction* itact = ink_toggle_action_new( "transform_pattern", + _("Move patterns"), + _("Move patterns (in fill or stroke) along with the objects"), + "transform_pattern", + Inkscape::ICON_SIZE_DECORATION ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs_get_int_attribute("options.transform", "pattern", 1) ); + g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_pattern), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); + } }