diff options
| author | Ted Gould <ted@gould.cx> | 2010-07-13 20:16:51 +0000 |
|---|---|---|
| committer | Ted Gould <ted@gould.cx> | 2010-07-13 20:16:51 +0000 |
| commit | ef2d72d29fce61231bdd7888ab8330503158e9d6 (patch) | |
| tree | 4685bfddef010181fdd87fc182016b994f2b69d9 /src/widgets | |
| parent | Pulling in a more recent trunk (diff) | |
| parent | Translations. Romanian nsh file update. (diff) | |
| download | inkscape-ef2d72d29fce61231bdd7888ab8330503158e9d6.tar.gz inkscape-ef2d72d29fce61231bdd7888ab8330503158e9d6.zip | |
Upgrading to trunk
(bzr r8254.1.57)
Diffstat (limited to 'src/widgets')
| -rw-r--r-- | src/widgets/desktop-widget.cpp | 6 | ||||
| -rw-r--r-- | src/widgets/fill-style.cpp | 46 | ||||
| -rw-r--r-- | src/widgets/gradient-selector.cpp | 108 | ||||
| -rw-r--r-- | src/widgets/gradient-selector.h | 4 | ||||
| -rw-r--r-- | src/widgets/gradient-toolbar.cpp | 40 | ||||
| -rw-r--r-- | src/widgets/gradient-vector.cpp | 17 | ||||
| -rw-r--r-- | src/widgets/paint-selector.cpp | 8 | ||||
| -rw-r--r-- | src/widgets/sp-color-notebook.cpp | 3 | ||||
| -rw-r--r-- | src/widgets/sp-color-scales.cpp | 26 | ||||
| -rw-r--r-- | src/widgets/swatch-selector.cpp | 8 | ||||
| -rw-r--r-- | src/widgets/toolbox.cpp | 579 |
11 files changed, 621 insertions, 224 deletions
diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index ab440595f..36047e81b 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1393,8 +1393,6 @@ SPViewWidget *sp_desktop_widget_new( SPNamedView *namedview ) { SPDesktopWidget* dtw = SPDesktopWidget::createInstance(namedview); - UXManager::getInstance()->addTrack(dtw); - return SP_VIEW_WIDGET(dtw); } @@ -1440,10 +1438,12 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) toolboxes.push_back(dtw->aux_toolbox); toolboxes.push_back(dtw->commands_toolbox); toolboxes.push_back(dtw->snap_toolbox); - UXManager::getInstance()->connectToDesktop( toolboxes, dtw->desktop ); dtw->panels->setDesktop( dtw->desktop ); + UXManager::getInstance()->addTrack(dtw); + UXManager::getInstance()->connectToDesktop( toolboxes, dtw->desktop ); + return dtw; } diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp index 15d8b6cc2..a0e343b58 100644 --- a/src/widgets/fill-style.cpp +++ b/src/widgets/fill-style.cpp @@ -268,15 +268,15 @@ void FillNStroke::performUpdate() psel->setGradientLinear( vector ); SPLinearGradient *lg = SP_LINEARGRADIENT(server); - psel->setGradientProperties( SP_GRADIENT_UNITS(lg), - SP_GRADIENT_SPREAD(lg) ); + psel->setGradientProperties( lg->getUnits(), + lg->getSpread() ); } else if (SP_IS_RADIALGRADIENT(server)) { SPGradient *vector = SP_GRADIENT(server)->getVector(); psel->setGradientRadial( vector ); SPRadialGradient *rg = SP_RADIALGRADIENT(server); - psel->setGradientProperties( SP_GRADIENT_UNITS(rg), - SP_GRADIENT_SPREAD(rg) ); + psel->setGradientProperties( rg->getUnits(), + rg->getSpread() ); } else if (SP_IS_PATTERN(server)) { SPPattern *pat = pattern_getroot(SP_PATTERN(server)); psel->updatePatternList( pat ); @@ -523,6 +523,7 @@ void FillNStroke::updateFromPaint() SPGradientType const gradient_type = ( psel->mode != SPPaintSelector::MODE_GRADIENT_RADIAL ? SP_GRADIENT_TYPE_LINEAR : SP_GRADIENT_TYPE_RADIAL ); + bool createSwatch = (psel->mode == SPPaintSelector::MODE_SWATCH); SPCSSAttr *css = 0; if (kind == FILL) { @@ -537,27 +538,34 @@ void FillNStroke::updateFromPaint() SPStyle *query = sp_style_new(desktop->doc()); int result = objects_query_fillstroke(const_cast<GSList *>(items), query, kind == FILL); - SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke; - guint32 common_rgb = 0; if (result == QUERY_STYLE_MULTIPLE_SAME) { + SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke; + SPColor common; if (!targPaint.isColor()) { - common_rgb = sp_desktop_get_color(desktop, kind == FILL); + common = sp_desktop_get_color(desktop, kind == FILL); } else { - common_rgb = targPaint.value.color.toRGBA32( 0xff ); + common = targPaint.value.color; + } + vector = sp_document_default_gradient_vector( document, common, createSwatch ); + if ( vector && createSwatch ) { + vector->setSwatch(); } - vector = sp_document_default_gradient_vector(document, common_rgb); } sp_style_unref(query); for (GSList const *i = items; i != NULL; i = i->next) { //FIXME: see above if (kind == FILL) { - sp_repr_css_change_recursive(SP_OBJECT_REPR(i->data), css, "style"); + sp_repr_css_change_recursive(reinterpret_cast<SPObject*>(i->data)->repr, css, "style"); } if (!vector) { + SPGradient *gr = sp_gradient_vector_for_object( document, desktop, reinterpret_cast<SPObject*>(i->data), kind == FILL, createSwatch ); + if ( gr && createSwatch ) { + gr->setSwatch(); + } sp_item_set_gradient(SP_ITEM(i->data), - sp_gradient_vector_for_object(document, desktop, SP_OBJECT(i->data), kind == FILL), + gr, gradient_type, kind == FILL); } else { sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, kind == FILL); @@ -570,7 +578,7 @@ void FillNStroke::updateFromPaint() for (GSList const *i = items; i != NULL; i = i->next) { //FIXME: see above if (kind == FILL) { - sp_repr_css_change_recursive(SP_OBJECT_REPR(i->data), css, "style"); + sp_repr_css_change_recursive(reinterpret_cast<SPObject*>(i->data)->repr, css, "style"); } SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, kind == FILL); @@ -600,7 +608,7 @@ void FillNStroke::updateFromPaint() */ } else { - Inkscape::XML::Node *patrepr = SP_OBJECT_REPR(pattern); + Inkscape::XML::Node *patrepr = pattern->repr; SPCSSAttr *css = sp_repr_css_attr_new(); gchar *urltext = g_strdup_printf("url(#%s)", patrepr->attribute("id")); sp_repr_css_set_property(css, (kind == FILL) ? "fill" : "stroke", urltext); @@ -614,17 +622,17 @@ void FillNStroke::updateFromPaint() // objects who already have the same root pattern but through a different href // chain. FIXME: move this to a sp_item_set_pattern for (GSList const *i = items; i != NULL; i = i->next) { - Inkscape::XML::Node *selrepr = SP_OBJECT_REPR(i->data); + Inkscape::XML::Node *selrepr = reinterpret_cast<SPObject*>(i->data)->repr; if ( (kind == STROKE) && !selrepr) { continue; } - SPObject *selobj = SP_OBJECT(i->data); + SPObject *selobj = reinterpret_cast<SPObject*>(i->data); - SPStyle *style = SP_OBJECT_STYLE(selobj); + SPStyle *style = selobj->style; if (style && ((kind == FILL) ? style->fill : style->stroke).isPaintserver()) { - SPObject *server = (kind == FILL) ? - SP_OBJECT_STYLE_FILL_SERVER(selobj) : - SP_OBJECT_STYLE_STROKE_SERVER(selobj); + SPPaintServer *server = (kind == FILL) ? + selobj->style->getFillPaintServer() : + selobj->style->getStrokePaintServer(); if (SP_IS_PATTERN(server) && pattern_getroot(SP_PATTERN(server)) == pattern) // only if this object's pattern is not rooted in our selected pattern, apply continue; diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index bc2413730..5b663c493 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -117,10 +117,10 @@ sp_gradient_selector_class_init (SPGradientSelectorClass *klass) object_class->destroy = sp_gradient_selector_destroy; } -static void -sp_gradient_selector_init (SPGradientSelector *sel) +static void sp_gradient_selector_init(SPGradientSelector *sel) { - GtkWidget *hb, *m, *mi; + sel->safelyInit = true; + new (&sel->nonsolid) std::vector<GtkWidget*>(); sel->mode = SPGradientSelector::MODE_LINEAR; @@ -134,39 +134,44 @@ sp_gradient_selector_init (SPGradientSelector *sel) g_signal_connect (G_OBJECT (sel->vectors), "vector_set", G_CALLBACK (sp_gradient_selector_vector_set), sel); /* Create box for buttons */ - hb = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (sel), hb, FALSE, FALSE, 0); + GtkWidget *hb = gtk_hbox_new( FALSE, 0 ); + sel->nonsolid.push_back(hb); + gtk_box_pack_start( GTK_BOX(sel), hb, FALSE, FALSE, 0 ); GtkTooltips *ttips = gtk_tooltips_new (); sel->add = gtk_button_new_with_label (_("Duplicate")); + sel->nonsolid.push_back(sel->add); gtk_box_pack_start (GTK_BOX (hb), sel->add, TRUE, TRUE, 0); g_signal_connect (G_OBJECT (sel->add), "clicked", G_CALLBACK (sp_gradient_selector_add_vector_clicked), sel); gtk_widget_set_sensitive (sel->add, FALSE); sel->edit = gtk_button_new_with_label (_("Edit...")); + sel->nonsolid.push_back(sel->edit); gtk_box_pack_start (GTK_BOX (hb), sel->edit, TRUE, TRUE, 0); g_signal_connect (G_OBJECT (sel->edit), "clicked", G_CALLBACK (sp_gradient_selector_edit_vector_clicked), sel); gtk_widget_set_sensitive (sel->edit, FALSE); - gtk_widget_show_all (hb); + gtk_widget_show_all(hb); /* Spread selector */ - hb = gtk_hbox_new (FALSE, 0); - gtk_widget_show (hb); - gtk_box_pack_start (GTK_BOX (sel), hb, FALSE, FALSE, 0); - - sel->spread = gtk_option_menu_new (); - gtk_widget_show (sel->spread); - gtk_box_pack_end (GTK_BOX (hb), sel->spread, FALSE, FALSE, 0); - gtk_tooltips_set_tip (ttips, sel->spread, + hb = gtk_hbox_new( FALSE, 0 ); + sel->nonsolid.push_back(hb); + gtk_widget_show(hb); + gtk_box_pack_start( GTK_BOX(sel), hb, FALSE, FALSE, 0 ); + + sel->spread = gtk_option_menu_new(); + sel->nonsolid.push_back(sel->spread); + gtk_widget_show(sel->spread); + gtk_box_pack_end( GTK_BOX(hb), sel->spread, FALSE, FALSE, 0 ); + gtk_tooltips_set_tip( ttips, sel->spread, // TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute _("Whether to fill with flat color beyond the ends of the gradient vector " "(spreadMethod=\"pad\"), or repeat the gradient in the same direction " "(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " "directions (spreadMethod=\"reflect\")"), NULL); - m = gtk_menu_new (); - mi = gtk_menu_item_new_with_label (_("none")); + GtkWidget *m = gtk_menu_new(); + GtkWidget *mi = gtk_menu_item_new_with_label(_("none")); gtk_menu_append (GTK_MENU (m), mi); g_object_set_data (G_OBJECT (mi), "gradientSpread", GUINT_TO_POINTER (SP_GRADIENT_SPREAD_PAD)); g_signal_connect (G_OBJECT (mi), "activate", G_CALLBACK (sp_gradient_selector_spread_activate), sel); @@ -180,22 +185,27 @@ sp_gradient_selector_init (SPGradientSelector *sel) gtk_menu_append (GTK_MENU (m), mi); gtk_widget_show_all (m); - gtk_option_menu_set_menu (GTK_OPTION_MENU (sel->spread), m); + gtk_option_menu_set_menu( GTK_OPTION_MENU(sel->spread), m ); - sel->spreadLbl = gtk_label_new (_("Repeat:")); - gtk_widget_show(sel->spreadLbl); - gtk_box_pack_end(GTK_BOX(hb), sel->spreadLbl, FALSE, FALSE, 4); + sel->spreadLbl = gtk_label_new( _("Repeat:") ); + sel->nonsolid.push_back(sel->spreadLbl); + gtk_widget_show( sel->spreadLbl ); + gtk_box_pack_end( GTK_BOX(hb), sel->spreadLbl, FALSE, FALSE, 4 ); } -static void -sp_gradient_selector_destroy (GtkObject *object) +static void sp_gradient_selector_destroy(GtkObject *object) { - SPGradientSelector *sel; + SPGradientSelector *sel = SP_GRADIENT_SELECTOR( object ); - sel = SP_GRADIENT_SELECTOR (object); + if ( sel->safelyInit ) { + sel->safelyInit = false; + using std::vector; + sel->nonsolid.~vector<GtkWidget*>(); + } - if (((GtkObjectClass *) (parent_class))->destroy) + if (((GtkObjectClass *) (parent_class))->destroy) { (* ((GtkObjectClass *) (parent_class))->destroy) (object); + } } GtkWidget * @@ -213,19 +223,9 @@ void SPGradientSelector::setMode(SelectorMode mode) if (mode != this->mode) { this->mode = mode; if (mode == MODE_SWATCH) { - if (spread) { - GtkWidget *parent = gtk_widget_get_parent(spread); - if (parent) { - gtk_container_remove(GTK_CONTAINER(parent), spread); - spread = 0; - } - } - if (spreadLbl) { - GtkWidget *parent = gtk_widget_get_parent(spreadLbl); - if (parent) { - gtk_container_remove(GTK_CONTAINER(parent), spreadLbl); - spreadLbl = 0; - } + for (std::vector<GtkWidget*>::iterator it = nonsolid.begin(); it != nonsolid.end(); ++it) + { + gtk_widget_hide(*it); } SPGradientVectorSelector* vs = SP_GRADIENT_VECTOR_SELECTOR(vectors); @@ -261,18 +261,40 @@ void SPGradientSelector::setVector(SPDocument *doc, SPGradient *vector) g_return_if_fail(!vector || SP_IS_GRADIENT(vector)); g_return_if_fail(!vector || (SP_OBJECT_DOCUMENT(vector) == doc)); - if (vector && !SP_GRADIENT_HAS_STOPS(vector)) { + if (vector && !vector->hasStops()) { return; } sp_gradient_vector_selector_set_gradient(SP_GRADIENT_VECTOR_SELECTOR(vectors), doc, vector); if (vector) { - gtk_widget_set_sensitive(edit, TRUE); - gtk_widget_set_sensitive(add, TRUE); + if ( (mode == MODE_SWATCH) && vector->isSwatch() ) { + if ( vector->isSolid() ) { + for (std::vector<GtkWidget*>::iterator it = nonsolid.begin(); it != nonsolid.end(); ++it) + { + gtk_widget_hide(*it); + } + } else { + for (std::vector<GtkWidget*>::iterator it = nonsolid.begin(); it != nonsolid.end(); ++it) + { + gtk_widget_show_all(*it); + } + } + } + + if (edit) { + gtk_widget_set_sensitive(edit, TRUE); + } + if (add) { + gtk_widget_set_sensitive(add, TRUE); + } } else { - gtk_widget_set_sensitive(edit, FALSE); - gtk_widget_set_sensitive(add, (doc != NULL)); + if (edit) { + gtk_widget_set_sensitive(edit, FALSE); + } + if (add) { + gtk_widget_set_sensitive(add, (doc != NULL)); + } } } diff --git a/src/widgets/gradient-selector.h b/src/widgets/gradient-selector.h index 25f561a6e..860804ec6 100644 --- a/src/widgets/gradient-selector.h +++ b/src/widgets/gradient-selector.h @@ -17,6 +17,7 @@ #include <glib.h> #include <gtk/gtkvbox.h> +#include <vector> #include "sp-gradient.h" #include "sp-gradient-spread.h" #include "sp-gradient-units.h" @@ -59,6 +60,9 @@ struct SPGradientSelector { GtkWidget *spread; GtkWidget *spreadLbl; + bool safelyInit; + std::vector<GtkWidget*> nonsolid; + void setMode(SelectorMode mode); void setUnits(SPGradientUnits units); void setSpread(SPGradientSpread spread); diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp index 077e038e7..ce5f5fb8f 100644 --- a/src/widgets/gradient-toolbar.cpp +++ b/src/widgets/gradient-toolbar.cpp @@ -73,18 +73,17 @@ static void gr_toggle_fillstroke (GtkWidget *button, gpointer data) { } } -void -gr_apply_gradient_to_item (SPItem *item, SPGradient *gr, SPGradientType new_type, guint new_fill, bool do_fill, bool do_stroke) +void gr_apply_gradient_to_item( SPItem *item, SPGradient *gr, SPGradientType new_type, guint new_fill, bool do_fill, bool do_stroke ) { - SPStyle *style = SP_OBJECT_STYLE (item); + SPStyle *style = item->style; if (do_fill) { if (style && (style->fill.isPaintserver()) && - SP_IS_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (item))) { - SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item); - if (SP_IS_LINEARGRADIENT (server)) { + SP_IS_GRADIENT( item->style->getFillPaintServer() )) { + SPPaintServer *server = item->style->getFillPaintServer(); + if ( SP_IS_LINEARGRADIENT(server) ) { sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, true); - } else if (SP_IS_RADIALGRADIENT (server)) { + } else if ( SP_IS_RADIALGRADIENT(server) ) { sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, true); } } else if (new_fill) { @@ -94,11 +93,11 @@ gr_apply_gradient_to_item (SPItem *item, SPGradient *gr, SPGradientType new_type if (do_stroke) { if (style && (style->stroke.isPaintserver()) && - SP_IS_GRADIENT (SP_OBJECT_STYLE_STROKE_SERVER (item))) { - SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item); - if (SP_IS_LINEARGRADIENT (server)) { + SP_IS_GRADIENT( item->style->getStrokePaintServer() )) { + SPPaintServer *server = item->style->getStrokePaintServer(); + if ( SP_IS_LINEARGRADIENT(server) ) { sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, false); - } else if (SP_IS_RADIALGRADIENT (server)) { + } else if ( SP_IS_RADIALGRADIENT(server) ) { sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, false); } } else if (!new_fill) { @@ -175,7 +174,7 @@ GtkWidget *gr_vector_list(SPDesktop *desktop, bool selection_empty, SPGradient * const GSList *gradients = sp_document_get_resource_list (document, "gradient"); for (const GSList *i = gradients; i != NULL; i = i->next) { SPGradient *grad = SP_GRADIENT(i->data); - if (SP_GRADIENT_HAS_STOPS(grad) && !grad->isSolid()) { + if ( grad->hasStops() && !grad->isSolid() ) { gl = g_slist_prepend (gl, i->data); } } @@ -238,7 +237,7 @@ GtkWidget *gr_vector_list(SPDesktop *desktop, bool selection_empty, SPGradient * GtkWidget *hb = gtk_hbox_new (FALSE, 4); GtkWidget *l = gtk_label_new (""); - gchar *label = gr_prepare_label (SP_OBJECT(gradient)); + gchar *label = gr_prepare_label(gradient); gtk_label_set_markup (GTK_LABEL(l), label); g_free (label); gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); @@ -310,13 +309,13 @@ void gr_read_selection( Inkscape::Selection *selection, // If no selected dragger, read desktop selection for (GSList const* i = selection->itemList(); i; i = i->next) { SPItem *item = SP_ITEM(i->data); - SPStyle *style = SP_OBJECT_STYLE (item); + SPStyle *style = item->style; if (style && (style->fill.isPaintserver())) { - SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item); - if (SP_IS_GRADIENT(server)) { + SPPaintServer *server = item->style->getFillPaintServer(); + if ( SP_IS_GRADIENT(server) ) { SPGradient *gradient = SP_GRADIENT(server)->getVector(); - SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server)); + SPGradientSpread spread = SP_GRADIENT(server)->fetchSpread(); if (gradient && gradient->isSolid()) { gradient = 0; @@ -339,14 +338,13 @@ void gr_read_selection( Inkscape::Selection *selection, } } if (style && (style->stroke.isPaintserver())) { - SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item); - if (SP_IS_GRADIENT(server)) { + SPPaintServer *server = item->style->getStrokePaintServer(); + if ( SP_IS_GRADIENT(server) ) { SPGradient *gradient = SP_GRADIENT(server)->getVector(); - SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server)); + SPGradientSpread spread = SP_GRADIENT(server)->fetchSpread(); if (gradient && gradient->isSolid()) { gradient = 0; - } if (gradient && (gradient != gr_selected)) { diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index 7bfe27310..c49d9e06f 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -174,6 +174,10 @@ GtkWidget *sp_gradient_vector_selector_new(SPDocument *doc, SPGradient *gr) void sp_gradient_vector_selector_set_gradient(SPGradientVectorSelector *gvs, SPDocument *doc, SPGradient *gr) { +// g_message("sp_gradient_vector_selector_set_gradient(%p, %p, %p) [%s] %d %d", gvs, doc, gr, +// (gr ? gr->getId():"N/A"), +// (gr ? gr->isSwatch() : -1), +// (gr ? gr->isSolid() : -1)); static gboolean suppress = FALSE; g_return_if_fail(gvs != NULL); @@ -181,7 +185,7 @@ void sp_gradient_vector_selector_set_gradient(SPGradientVectorSelector *gvs, SPD g_return_if_fail(!gr || (doc != NULL)); g_return_if_fail(!gr || SP_IS_GRADIENT(gr)); g_return_if_fail(!gr || (SP_OBJECT_DOCUMENT(gr) == doc)); - g_return_if_fail(!gr || SP_GRADIENT_HAS_STOPS(gr)); + g_return_if_fail(!gr || gr->hasStops()); if (doc != gvs->doc) { /* Disconnect signals */ @@ -252,7 +256,7 @@ static void sp_gvs_rebuild_gui_full(SPGradientVectorSelector *gvs) const GSList *gradients = sp_document_get_resource_list(SP_OBJECT_DOCUMENT(gvs->gr), "gradient"); for (const GSList *curr = gradients; curr; curr = curr->next) { SPGradient* grad = SP_GRADIENT(curr->data); - if (SP_GRADIENT_HAS_STOPS(grad) && (grad->isSwatch() == gvs->swatched)) { + if ( grad->hasStops() && (grad->isSwatch() == gvs->swatched) ) { gl = g_slist_prepend(gl, curr->data); } } @@ -337,6 +341,7 @@ static void sp_gvs_gradient_activate(GtkMenuItem *mi, SPGradientVectorSelector * /* Hmmm - probably we can just re-set it as menuitem data (Lauris) */ //g_print("SPGradientVectorSelector: gradient %s activated\n", SP_OBJECT_ID(gr)); + //g_message("Setting to gradient %p swatch:%d solid:%d", gr, gr->isSwatch(), gr->isSolid()); norm = sp_gradient_ensure_vector_normalized(gr); if (norm != gr) { @@ -535,7 +540,7 @@ static void update_stop_list( GtkWidget *mnu, SPGradient *gradient, SPStop *new_ GtkWidget *m = gtk_menu_new(); gtk_widget_show(m); GSList *sl = NULL; - if (gradient->has_stops) { + if ( gradient->hasStops() ) { for ( SPObject *ochild = sp_object_first_child(SP_OBJECT(gradient)) ; ochild != NULL ; ochild = SP_OBJECT_NEXT(ochild) ) { if (SP_IS_STOP(ochild)) { sl = g_slist_append(sl, ochild); @@ -1017,7 +1022,7 @@ static void sp_gradient_vector_widget_load_gradient(GtkWidget *widget, SPGradien if (gradient) { gtk_widget_set_sensitive(widget, TRUE); - sp_gradient_ensure_vector(gradient); + gradient->ensureVector(); GtkOptionMenu *mnu = static_cast<GtkOptionMenu *>(g_object_get_data(G_OBJECT(widget), "stopmenu")); SPStop *stop = SP_STOP(g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(mnu)))), "stop")); @@ -1140,7 +1145,7 @@ static void sp_gradient_vector_color_dragged(SPColorSelector *csel, GtkObject *o sp_gradient_vector_widget_load_gradient(GTK_WIDGET(object), ngr); } - sp_gradient_ensure_vector(ngr); + ngr->ensureVector(); GtkOptionMenu *mnu = static_cast<GtkOptionMenu *>(g_object_get_data(G_OBJECT(object), "stopmenu")); SPStop *stop = SP_STOP(g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(mnu)))), "stop")); @@ -1175,7 +1180,7 @@ static void sp_gradient_vector_color_changed(SPColorSelector *csel, GtkObject *o sp_gradient_vector_widget_load_gradient(GTK_WIDGET(object), ngr); } - sp_gradient_ensure_vector(ngr); + ngr->ensureVector(); /* Set start parameters */ /* We rely on normalized vector, i.e. stops HAVE to exist */ diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index d3092669a..cf6a04a3c 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -538,8 +538,8 @@ void SPPaintSelector::pushAttrsToGradient( SPGradient *gr ) const SPGradientUnits units = SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX; SPGradientSpread spread = SP_GRADIENT_SPREAD_PAD; getGradientProperties( units, spread ); - sp_gradient_set_units(gr, units); - sp_gradient_set_spread(gr, spread); + gr->setUnits(units); + gr->setSpread(spread); SP_OBJECT(gr)->updateRepr(); } @@ -1082,11 +1082,10 @@ static void sp_paint_selector_set_mode_swatch(SPPaintSelector *psel, SPPaintSele SwatchSelector *swatchsel = 0; if (psel->mode == SPPaintSelector::MODE_SWATCH){ - /* Already have pattern menu */ swatchsel = static_cast<SwatchSelector*>(g_object_get_data(G_OBJECT(psel->selector), "swatch-selector")); } else { sp_paint_selector_clear_frame(psel); - /* Create new gradient selector */ + // Create new gradient selector SwatchSelector *swatchsel = new SwatchSelector(); swatchsel->show(); @@ -1102,6 +1101,7 @@ static void sp_paint_selector_set_mode_swatch(SPPaintSelector *psel, SPPaintSele gtk_frame_set_label(GTK_FRAME(psel->frame), _("Swatch fill")); } + #ifdef SP_PS_VERBOSE g_print("Swatch req\n"); #endif diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp index a249786ff..6c5113084 100644 --- a/src/widgets/sp-color-notebook.cpp +++ b/src/widgets/sp-color-notebook.cpp @@ -519,6 +519,7 @@ void ColorNotebook::_rgbaEntryChanged(GtkEntry* entry) } } +// TODO pass in param so as to avoid the need for SP_ACTIVE_DOCUMENT void ColorNotebook::_updateRgbaEntry( const SPColor& color, gfloat alpha ) { g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) ); @@ -539,7 +540,7 @@ void ColorNotebook::_updateRgbaEntry( const SPColor& color, gfloat alpha ) gtk_widget_set_sensitive (_box_toomuchink, false); if (color.icc){ Inkscape::ColorProfile* prof = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str()); - if (prof->getColorSpace() == icSigCmykData || prof->getColorSpace() == icSigCmyData){ + if ( prof && ( (prof->getColorSpace() == icSigCmykData) || (prof->getColorSpace() == icSigCmyData) ) ) { gtk_widget_show(GTK_WIDGET(_box_toomuchink)); double ink_sum = 0; for (unsigned int i=0; i<color.icc->colors.size(); i++){ diff --git a/src/widgets/sp-color-scales.cpp b/src/widgets/sp-color-scales.cpp index e41b81e5c..d20cf65ef 100644 --- a/src/widgets/sp-color-scales.cpp +++ b/src/widgets/sp-color-scales.cpp @@ -11,7 +11,6 @@ #include "../dialogs/dialog-events.h" #include "sp-color-scales.h" #include "svg/svg-icc-color.h" -#include "svg/svg-device-color.h" #define CSC_CHANNEL_R (1 << 0) #define CSC_CHANNEL_G (1 << 1) @@ -232,12 +231,6 @@ void ColorScales::_recalcColor( gboolean changing ) case SP_COLOR_SCALES_MODE_CMYK: { _getCmykaFloatv( c ); - color.device = new SVGDeviceColor(); - color.device->type=DEVICE_CMYK; - color.device->colors.clear(); - for (int i=0;i<4;i++){ - color.device->colors.push_back(c[i]); - } float rgb[3]; sp_color_cmyk_to_rgb_floatv( rgb, c[0], c[1], c[2], c[3] ); @@ -483,19 +476,12 @@ void ColorScales::setMode(SPColorScalesMode mode) gtk_widget_show (_b[4]); _updating = TRUE; - if (_color.device && _color.device->type == DEVICE_CMYK){ - setScaled( _a[0], _color.device->colors[0] ); - setScaled( _a[1], _color.device->colors[1] ); - setScaled( _a[2], _color.device->colors[2] ); - setScaled( _a[3], _color.device->colors[3] ); - } else { - //If we still dont have a device-color, convert from rbga - sp_color_rgb_to_cmyk_floatv (c, rgba[0], rgba[1], rgba[2]); - setScaled( _a[0], c[0] ); - setScaled( _a[1], c[1] ); - setScaled( _a[2], c[2] ); - setScaled( _a[3], c[3] ); - } + sp_color_rgb_to_cmyk_floatv (c, rgba[0], rgba[1], rgba[2]); + setScaled( _a[0], c[0] ); + setScaled( _a[1], c[1] ); + setScaled( _a[2], c[2] ); + setScaled( _a[3], c[3] ); + setScaled( _a[4], rgba[3] ); _updating = FALSE; _updateSliders( CSC_CHANNELS_ALL ); diff --git a/src/widgets/swatch-selector.cpp b/src/widgets/swatch-selector.cpp index a6f5133b7..88abca358 100644 --- a/src/widgets/swatch-selector.cpp +++ b/src/widgets/swatch-selector.cpp @@ -116,7 +116,7 @@ void SwatchSelector::_changedCb(SPColorSelector */*csel*/, void *data) // TODO replace with proper - sp_gradient_vector_widget_load_gradient(GTK_WIDGET(swsel->_gsel), ngr); } - sp_gradient_ensure_vector(ngr); + ngr->ensureVector(); SPStop* stop = ngr->getFirstStop(); @@ -169,10 +169,9 @@ void SwatchSelector::connectchangedHandler( GCallback handler, void *data ) void SwatchSelector::setVector(SPDocument */*doc*/, SPGradient *vector) { //GtkVBox * box = gobj(); - _gsel->setVector((vector) ? SP_OBJECT_DOCUMENT(vector) : 0, vector); - if (vector) { + if ( vector && vector->isSolid() ) { SPStop* stop = vector->getFirstStop(); guint32 const colorVal = sp_stop_get_rgba32(stop); @@ -180,6 +179,9 @@ void SwatchSelector::setVector(SPDocument */*doc*/, SPGradient *vector) SPColor color( SP_RGBA32_R_F(colorVal), SP_RGBA32_G_F(colorVal), SP_RGBA32_B_F(colorVal) ); // set its color, from the stored array _csel->base->setColor( color ); + gtk_widget_show_all( GTK_WIDGET(_csel) ); + } else { + gtk_widget_hide( GTK_WIDGET(_csel) ); } /* diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index de97e9ea4..bdf1e6ff2 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -85,6 +85,8 @@ #include "../sp-text.h" #include "../style.h" #include "../svg/css-ostringstream.h" +#include "../text-context.h" +#include "../text-editing.h" #include "../tools-switch.h" #include "../tweak-context.h" #include "../spray-context.h" @@ -106,7 +108,6 @@ #include "toolbox.h" -#define ENABLE_TASK_SUPPORT 1 //#define DEBUG_TEXT using Inkscape::UnitTracker; @@ -145,14 +146,6 @@ static void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mai static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); static void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -#if ENABLE_TASK_SUPPORT -static void fireTaskChange( EgeSelectOneAction *act, SPDesktop *dt ) -{ - gint selected = ege_select_one_action_get_active( act ); - UXManager::getInstance()->setTask(dt, selected); -} -#endif // ENABLE_TASK_SUPPORT - using Inkscape::UI::ToolboxFactory; @@ -487,9 +480,15 @@ static gchar const * ui_descr = " <separator />" " <toolitem action='TextAlignAction' />" " <separator />" + " <toolitem action='TextSuperscriptAction' />" + " <toolitem action='TextSubscriptAction' />" + " <separator />" " <toolitem action='TextLineHeightAction' />" " <toolitem action='TextLetterSpacingAction' />" " <toolitem action='TextWordSpacingAction' />" + " <toolitem action='TextDxAction' />" + " <toolitem action='TextDyAction' />" + " <toolitem action='TextRotationAction' />" " <separator />" " <toolitem action='TextOrientationAction' />" " </toolbar>" @@ -970,44 +969,6 @@ static Glib::RefPtr<Gtk::ActionGroup> create_or_fetch_actions( SPDesktop* deskto } } -#if ENABLE_TASK_SUPPORT - if ( !mainActions->get_action("TaskSetAction") ) { - GtkListStore* model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_STRING ); - - GtkTreeIter iter; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Default"), - 1, _("Default interface setup"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Custom"), - 1, _("Set the custom task"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Wide"), - 1, _("Setup for widescreen work"), - -1 ); - - EgeSelectOneAction* act = ege_select_one_action_new( "TaskSetAction", _("Task"), (""), NULL, GTK_TREE_MODEL(model) ); - g_object_set( act, "short_label", _("Task:"), NULL ); - mainActions->add(Glib::wrap(GTK_ACTION(act))); - //g_object_set_data( holder, "mode_action", act ); - - ege_select_one_action_set_appearance( act, "minimal" ); - ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); - //ege_select_one_action_set_icon_size( act, secondarySize ); - ege_select_one_action_set_tooltip_column( act, 1 ); - - //ege_select_one_action_set_active( act, mode ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(fireTaskChange), desktop ); - } -#endif // ENABLE_TASK_SUPPORT - return mainActions; } @@ -1031,7 +992,8 @@ static GtkWidget* toolboxNewCommon( GtkWidget* tb, BarId id, GtkPositionType han gtk_widget_set_sensitive(tb, FALSE); GtkWidget *hb = 0; - if ( UXManager::getInstance()->isFloatWindowProblem() ) { + gboolean forceFloatAllowed = Inkscape::Preferences::get()->getBool("/options/workarounds/floatallowed", false); + if ( UXManager::getInstance()->isFloatWindowProblem() && !forceFloatAllowed ) { hb = gtk_event_box_new(); // A simple, neutral container. } else { hb = gtk_handle_box_new(); @@ -1853,26 +1815,40 @@ void setup_tool_toolbox(GtkWidget *toolbox, SPDesktop *desktop) gchar const * descr = "<ui>" " <toolbar name='ToolToolbar'>" + + " <!-- Basics -->" " <toolitem action='ToolSelector' />" " <toolitem action='ToolNode' />" " <toolitem action='ToolTweak' />" - " <toolitem action='ToolSpray' />" " <toolitem action='ToolZoom' />" + + " <!-- Shapes -->" " <toolitem action='ToolRect' />" " <toolitem action='Tool3DBox' />" " <toolitem action='ToolArc' />" " <toolitem action='ToolStar' />" " <toolitem action='ToolSpiral' />" + + " <!-- Paths -->" " <toolitem action='ToolPencil' />" " <toolitem action='ToolPen' />" " <toolitem action='ToolCalligraphic' />" + + " <!-- Text -->" + " <toolitem action='ToolText' />" + + " <!-- Paint large areas -->" + " <toolitem action='ToolSpray' />" " <toolitem action='ToolEraser' />" -// " <toolitem action='ToolLPETool' />" + + " <!-- Fill -->" " <toolitem action='ToolPaintBucket' />" - " <toolitem action='ToolText' />" - " <toolitem action='ToolConnector' />" " <toolitem action='ToolGradient' />" " <toolitem action='ToolDropper' />" + + " <toolitem action='ToolConnector' />" + +// " <toolitem action='ToolLPETool' />" " </toolbar>" "</ui>"; @@ -2039,10 +2015,6 @@ void setup_commands_toolbox(GtkWidget *toolbox, SPDesktop *desktop) " <separator />" " <toolitem action='DialogPreferences' />" " <toolitem action='DialogDocumentProperties' />" -#if ENABLE_TASK_SUPPORT - " <separator />" - " <toolitem action='TaskSetAction' />" -#endif // ENABLE_TASK_SUPPORT " </toolbar>" "</ui>"; @@ -6605,6 +6577,82 @@ static void sp_text_style_changed( InkToggleAction* act, GObject *tbl ) g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } +// Handles both Superscripts and Subscripts +static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + // Called by Superscript or Subscript button? + const gchar* name = gtk_action_get_name( GTK_ACTION( act ) ); + gint prop = (strcmp(name, "TextSuperscriptAction") == 0) ? 0 : 1; + +#ifdef DEBUG_TEXT + std::cout << "sp_text_script_changed: " << prop << std::endl; +#endif + + // Query baseline + SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_BASELINES); + + bool setSuper = false; + bool setSub = false; + + if(result_baseline == QUERY_STYLE_NOTHING || result_baseline == QUERY_STYLE_MULTIPLE_DIFFERENT ) { + // If not set or mixed, turn on superscript or subscript + if( prop == 0 ) { + setSuper = true; + } else { + setSub = true; + } + } else { + // Superscript + gboolean superscriptSet = (query->baseline_shift.set && + query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); + + // Subscript + gboolean subscriptSet = (query->baseline_shift.set && + query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); + + setSuper = !superscriptSet && prop == 0; + setSub = !subscriptSet && prop == 1; + } + + // Set css properties + SPCSSAttr *css = sp_repr_css_attr_new (); + if( setSuper || setSub ) { + // Openoffice 2.3 and Adobe use 58%, Microsoft Word 2002 uses 65%, LaTex about 70%. + // 58% looks too small to me, especially if a superscript is placed on a superscript. + // If you make a change here, consider making a change to baseline-shift amount + // in style.cpp. + sp_repr_css_set_property (css, "font-size", "65%"); + } else { + sp_repr_css_set_property (css, "font-size", ""); + } + if( setSuper ) { + sp_repr_css_set_property (css, "baseline-shift", "super"); + } else if( setSub ) { + sp_repr_css_set_property (css, "baseline-shift", "sub"); + } else { + sp_repr_css_set_property (css, "baseline-shift", "baseline"); + } + + // Apply css to selected objects. + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css, true, false); + + // Save for undo + sp_document_maybe_done (sp_desktop_document (SP_ACTIVE_DESKTOP), "ttb:script", SP_VERB_NONE, + _("Text: Change superscript or subscript")); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) { // quit if run by the _changed callbacks @@ -6769,7 +6817,17 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) // Apply line-height to selected objects. SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, true); + sp_desktop_set_style (desktop, css, true, false); + + + // Until deprecated sodipodi:linespacing purged: + Inkscape::Selection *selection = sp_desktop_selection(desktop); + GSList const *items = selection->itemList(); + for (; items != NULL; items = items->next) { + if (SP_IS_TEXT (items->data)) { + SP_OBJECT_REPR(items->data)->setAttribute("sodipodi:linespacing", sp_repr_css_property (css, "line-height", NULL)); + } + } // Save for undo sp_document_maybe_done (sp_desktop_document (SP_ACTIVE_DESKTOP), "ttb:line-height", SP_VERB_NONE, @@ -6803,12 +6861,12 @@ static void sp_text_wordspacing_value_changed( GtkAdjustment *adj, GObject *tbl // Set css word-spacing SPCSSAttr *css = sp_repr_css_attr_new (); Inkscape::CSSOStringStream osfs; - osfs << adj->value; + osfs << adj->value << "px"; // For now always use px sp_repr_css_set_property (css, "word-spacing", osfs.str().c_str()); // Apply word-spacing to selected objects. SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, true); + sp_desktop_set_style (desktop, css, true, false); // Save for undo sp_document_maybe_done (sp_desktop_document (SP_ACTIVE_DESKTOP), "ttb:word-spacing", SP_VERB_NONE, @@ -6842,12 +6900,12 @@ static void sp_text_letterspacing_value_changed( GtkAdjustment *adj, GObject *tb // Set css letter-spacing SPCSSAttr *css = sp_repr_css_attr_new (); Inkscape::CSSOStringStream osfs; - osfs << adj->value; + osfs << adj->value << "px"; // For now always use px sp_repr_css_set_property (css, "letter-spacing", osfs.str().c_str()); // Apply letter-spacing to selected objects. SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, true); + sp_desktop_set_style (desktop, css, true, false); // Save for undo sp_document_maybe_done (sp_desktop_document (SP_ACTIVE_DESKTOP), "ttb:letter-spacing", SP_VERB_NONE, @@ -6869,6 +6927,100 @@ static void sp_text_letterspacing_value_changed( GtkAdjustment *adj, GObject *tb g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } + +static void sp_text_dx_value_changed( GtkAdjustment *adj, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + gdouble new_dx = adj->value; + + if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { + SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); + if( tc ) { + unsigned char_index = -1; + TextTagAttributes *attributes = + text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); + if( attributes ) { + double old_dx = attributes->getDx( char_index ); + double delta_dx = new_dx - old_dx; + sp_te_adjust_dx( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_dx ); + } + } + } + + // Save for undo + sp_document_maybe_done (sp_desktop_document (SP_ACTIVE_DESKTOP), "ttb:dx", SP_VERB_NONE, + _("Text: Change dx (kern)")); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_text_dy_value_changed( GtkAdjustment *adj, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + gdouble new_dy = adj->value; + + if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { + SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); + if( tc ) { + unsigned char_index = -1; + TextTagAttributes *attributes = + text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); + if( attributes ) { + double old_dy = attributes->getDy( char_index ); + double delta_dy = new_dy - old_dy; + sp_te_adjust_dy( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_dy ); + } + } + } + + // Save for undo + sp_document_maybe_done (sp_desktop_document (SP_ACTIVE_DESKTOP), "ttb:dy", SP_VERB_NONE, + _("Text: Change dy")); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_text_rotation_value_changed( GtkAdjustment *adj, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + gdouble new_degrees = adj->value; + + if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { + SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); + if( tc ) { + unsigned char_index = -1; + TextTagAttributes *attributes = + text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); + if( attributes ) { + double old_degrees = attributes->getRotate( char_index ); + double delta_deg = new_degrees - old_degrees; + sp_te_adjust_rotation( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_deg ); + } + } + } + + // Save for undo + sp_document_maybe_done (sp_desktop_document (SP_ACTIVE_DESKTOP), "ttb:rotate", SP_VERB_NONE, + _("Text: Change rotate")); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + static void sp_text_orientation_mode_changed( EgeSelectOneAction *act, GObject *tbl ) { // quit if run by the _changed callbacks @@ -6938,6 +7090,9 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ const gchar* id = SP_OBJECT_ID((SPItem *) items->data); std::cout << " " << id << std::endl; } + Glib::ustring selected_text = sp_text_get_selected_text((SP_ACTIVE_DESKTOP)->event_context); + std::cout << " Selected text:" << std::endl; + std::cout << selected_text << std::endl; #endif // quit if run by the _changed callbacks @@ -6951,6 +7106,21 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + // Only flowed text can be justified, only normal text can be kerned... + // Find out if we have flowed text now so we can use it several places + gboolean isFlow = false; + for (GSList const *items = sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList(); + items != NULL; + items = items->next) { + // const gchar* id = SP_OBJECT_ID((SPItem *) items->data); + // std::cout << " " << id << std::endl; + if( SP_IS_FLOWTEXT(( SPItem *) items->data )) { + isFlow = true; + // std::cout << " Found flowed text" << std::endl; + break; + } + } + /* * Query from current selection: * Font family (font-family) @@ -6963,6 +7133,8 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_BASELINES); + // Used later: sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); @@ -7007,6 +7179,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ ink_comboboxentry_action_set_active_text( fontFamilyAction, fontFamily ); } + // Size (average of text selected) double size = query->font_size.computed; gchar size_text[G_ASCII_DTOSTR_BUF_SIZE]; @@ -7016,6 +7189,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontSizeAction" ) ); ink_comboboxentry_action_set_active_text( fontSizeAction, size_text ); + // Weight (Bold) // Note: in the enumeration, normal and lighter come at the end so we must explicitly test for them. gboolean boldSet = ((query->font_weight.computed >= SP_CSS_FONT_WEIGHT_700) && @@ -7033,31 +7207,47 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textItalicAction), italicSet ); + // Superscript + gboolean superscriptSet = + ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && + query->baseline_shift.set && + query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); + + InkToggleAction* textSuperscriptAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextSuperscriptAction" ) ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textSuperscriptAction), superscriptSet ); + + + // Subscript + gboolean subscriptSet = + ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && + query->baseline_shift.set && + query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); + + InkToggleAction* textSubscriptAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextSubscriptAction" ) ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textSubscriptAction), subscriptSet ); + + // Alignment + EgeSelectOneAction* textAlignAction = EGE_SELECT_ONE_ACTION( g_object_get_data( tbl, "TextAlignAction" ) ); + // Note: SVG 1.1 doesn't include text-align, SVG 1.2 Tiny doesn't include text-align="justify" // text-align="justify" was a draft SVG 1.2 item (along with flowed text). // Only flowed text can be left and right justified at the same time. - // Check if we have flowed text and disable botton. - // NEED: ege_select_one_action_set_sensitve( ) - /* - gboolean isFlow = false; - for (GSList const *items = sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList(); - items != NULL; - items = items->next) { - const gchar* id = SP_OBJECT_ID((SPItem *) items->data); - std::cout << " " << id << std::endl; - if( SP_IS_FLOWTEXT(( SPItem *) items->data )) { - isFlow = true; - std::cout << " Found flowed text" << std::endl; - break; - } - } - if( isFlow ) { - // enable justify button - } else { - // disable justify button - } - */ + // Disable button if we don't have flowed text. + + // The GtkTreeModel class doesn't have a set function so we can't + // simply add an ege_select_one_action_set_sensitive method! + // We must set values directly with the GtkListStore and then + // ask that the GtkAction update the sensitive parameters. + GtkListStore * model = GTK_LIST_STORE( ege_select_one_action_get_model( textAlignAction ) ); + GtkTreePath * path = gtk_tree_path_new_from_string("3"); // Justify entry + GtkTreeIter iter; + gtk_tree_model_get_iter( GTK_TREE_MODEL (model), &iter, path ); + gtk_list_store_set( model, &iter, /* column */ 3, isFlow, -1 ); + ege_select_one_action_update_sensitive( textAlignAction ); + // ege_select_one_action_set_sensitive( textAlignAction, 3, isFlow ); int activeButton = 0; if (query->text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) @@ -7068,7 +7258,6 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) activeButton = 1; if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_END) activeButton = 2; } - EgeSelectOneAction* textAlignAction = EGE_SELECT_ONE_ACTION( g_object_get_data( tbl, "TextAlignAction" ) ); ege_select_one_action_set_active( textAlignAction, activeButton ); @@ -7099,7 +7288,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ GtkAdjustment *wordSpacingAdjustment = ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( wordSpacingAction )); gtk_adjustment_set_value( wordSpacingAdjustment, wordSpacing ); - + // Letter spacing double letterSpacing; @@ -7141,12 +7330,68 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ << " letter_spacing.value: " << query->letter_spacing.value << " letter_spacing.unit: " << query->letter_spacing.unit << std::endl; std::cout << " GUI: writing_mode.computed: " << query->writing_mode.computed << std::endl; - std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; - std::cout << std::endl; #endif sp_style_unref(query); + // Kerning (xshift), yshift, rotation. NB: These are not CSS attributes. + if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { + SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); + if( tc ) { + unsigned char_index = -1; + TextTagAttributes *attributes = + text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); + if( attributes ) { + + // Dx + double dx = attributes->getDx( char_index ); + GtkAction* dxAction = GTK_ACTION( g_object_get_data( tbl, "TextDxAction" )); + GtkAdjustment *dxAdjustment = + ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( dxAction )); + gtk_adjustment_set_value( dxAdjustment, dx ); + + // Dy + double dy = attributes->getDy( char_index ); + GtkAction* dyAction = GTK_ACTION( g_object_get_data( tbl, "TextDyAction" )); + GtkAdjustment *dyAdjustment = + ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( dyAction )); + gtk_adjustment_set_value( dyAdjustment, dy ); + + // Rotation + double rotation = attributes->getRotate( char_index ); + /* SVG value is between 0 and 360 but we're using -180 to 180 in widget */ + if( rotation > 180.0 ) rotation -= 360.0; + GtkAction* rotationAction = GTK_ACTION( g_object_get_data( tbl, "TextRotationAction" )); + GtkAdjustment *rotationAdjustment = + ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( rotationAction )); + gtk_adjustment_set_value( rotationAdjustment, rotation ); + +#ifdef DEBUG_TEXT + std::cout << " GUI: Dx: " << dx << std::endl; + std::cout << " GUI: Dy: " << dy << std::endl; + std::cout << " GUI: Rotation: " << rotation << std::endl; +#endif + } + } + } + + { + // Set these here as we don't always have kerning/rotating attributes + GtkAction* dxAction = GTK_ACTION( g_object_get_data( tbl, "TextDxAction" )); + gtk_action_set_sensitive( GTK_ACTION(dxAction), !isFlow ); + + GtkAction* dyAction = GTK_ACTION( g_object_get_data( tbl, "TextDyAction" )); + gtk_action_set_sensitive( GTK_ACTION(dyAction), !isFlow ); + + GtkAction* rotationAction = GTK_ACTION( g_object_get_data( tbl, "TextRotationAction" )); + gtk_action_set_sensitive( GTK_ACTION(rotationAction), !isFlow ); + } + +#ifdef DEBUG_TEXT + std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; + std::cout << std::endl; +#endif + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } @@ -7221,7 +7466,7 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontSizeAction", _("Font Size"), - _("Select Font Size"), + _("Font size (px)"), NULL, GTK_TREE_MODEL(model_size), 4 ); // Width in characters @@ -7234,7 +7479,7 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions { InkToggleAction* act = ink_toggle_action_new( "TextBoldAction", // Name _("Toggle Bold"), // Label - _("Toggle On/Off Bold Style"), // Tooltip + _("Toggle bold or normal weight"), // Tooltip GTK_STOCK_BOLD, // Icon (inkId) secondarySize ); // Icon size gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); @@ -7247,7 +7492,7 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions { InkToggleAction* act = ink_toggle_action_new( "TextItalicAction", // Name _("Toggle Italic/Oblique"), // Label - _("Toggle On/Off Italic/Oblique Style"),// Tooltip + _("Toggle italic/oblique style"),// Tooltip GTK_STOCK_ITALIC, // Icon (inkId) secondarySize ); // Icon size gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); @@ -7256,9 +7501,35 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions g_object_set_data( holder, "TextItalicAction", act ); } + /* Style - Superscript */ + { + InkToggleAction* act = ink_toggle_action_new( "TextSuperscriptAction", // Name + _("Toggle Superscript"), // Label + _("Toggle superscript"), // Tooltip + "text_superscript", // Icon (inkId) + secondarySize ); // Icon size + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_script_changed), holder ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/super", false) ); + g_object_set_data( holder, "TextSuperscriptAction", act ); + } + + /* Style - Subscript */ + { + InkToggleAction* act = ink_toggle_action_new( "TextSubscriptAction", // Name + _("Toggle Subscript"), // Label + _("Toggle subscript"), // Tooltip + "text_subscript", // Icon (inkId) + secondarySize ); // Icon size + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_script_changed), holder ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/sub", false) ); + g_object_set_data( holder, "TextSubscriptAction", act ); + } + /* Alignment */ { - GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); + GtkListStore* model = gtk_list_store_new( 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN ); GtkTreeIter iter; @@ -7267,6 +7538,7 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions 0, _("Align left"), 1, _("Align left"), 2, GTK_STOCK_JUSTIFY_LEFT, + 3, true, -1 ); gtk_list_store_append( model, &iter ); @@ -7274,6 +7546,7 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions 0, _("Align center"), 1, _("Align center"), 2, GTK_STOCK_JUSTIFY_CENTER, + 3, true, -1 ); gtk_list_store_append( model, &iter ); @@ -7281,21 +7554,23 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions 0, _("Align right"), 1, _("Align right"), 2, GTK_STOCK_JUSTIFY_RIGHT, + 3, true, -1 ); gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, 0, _("Justify"), - 1, _("Justify - Only flowed text"), + 1, _("Justify (only flowed text)"), 2, GTK_STOCK_JUSTIFY_FILL, + 3, false, -1 ); EgeSelectOneAction* act = ege_select_one_action_new( "TextAlignAction", // Name _("Alignment"), // Label - _("Text Alignment"), // Tooltip + _("Text alignment"), // Tooltip NULL, // StockID GTK_TREE_MODEL(model) ); // Model - g_object_set( act, "short_label", _("Align"), NULL ); + g_object_set( act, "short_label", "NotUsed", NULL ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); g_object_set_data( holder, "TextAlignAction", act ); @@ -7305,7 +7580,7 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions ege_select_one_action_set_icon_column( act, 2 ); ege_select_one_action_set_icon_size( act, secondarySize ); ege_select_one_action_set_tooltip_column( act, 1 ); - + ege_select_one_action_set_sensitive_column( act, 3 ); gint mode = prefs->getInt("/tools/text/align_mode", 0); ege_select_one_action_set_active( act, mode ); g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_text_align_mode_changed), holder ); @@ -7320,24 +7595,24 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, 0, _("Horizontal"), - 1, _("Horizontal Text"), + 1, _("Horizontal text"), 2, INKSCAPE_ICON_FORMAT_TEXT_DIRECTION_HORIZONTAL, -1 ); gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, 0, _("Vertical"), - 1, _("Vertical Text"), + 1, _("Vertical text"), 2, INKSCAPE_ICON_FORMAT_TEXT_DIRECTION_VERTICAL, -1 ); EgeSelectOneAction* act = ege_select_one_action_new( "TextOrientationAction", // Name _("Orientation"), // Label - _("Text Orientation"), // Tooltip + _("Text orientation"), // Tooltip NULL, // StockID GTK_TREE_MODEL(model) ); // Model - g_object_set( act, "short_label", _("O:"), NULL ); + g_object_set( act, "short_label", "NotUsed", NULL ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); g_object_set_data( holder, "TextOrientationAction", act ); @@ -7363,8 +7638,8 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions "TextLineHeightAction", /* name */ _("Line Height"), /* label */ _("Line:"), /* short label */ - _("Spacing between lines."), /* tooltip */ - "/tools/text/lineheight", /* path? */ + _("Spacing between lines (times font size)"), /* tooltip */ + "/tools/text/lineheight", /* preferences path */ 0.0, /* default */ GTK_WIDGET(desktop->canvas), /* focusTarget */ NULL, /* unit selector */ @@ -7381,6 +7656,7 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); g_object_set_data( holder, "TextLineHeightAction", eact ); + g_object_set( G_OBJECT(eact), "iconId", "text_line_spacing", NULL ); } /* Word spacing */ @@ -7393,8 +7669,8 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions "TextWordSpacingAction", /* name */ _("Word spacing"), /* label */ _("Word:"), /* short label */ - _("Spacing between words."), /* tooltip */ - "/tools/text/wordspacing", /* path? */ + _("Spacing between words (px)"), /* tooltip */ + "/tools/text/wordspacing", /* preferences path */ 0.0, /* default */ GTK_WIDGET(desktop->canvas), /* focusTarget */ NULL, /* unit selector */ @@ -7411,6 +7687,7 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); g_object_set_data( holder, "TextWordSpacingAction", eact ); + g_object_set( G_OBJECT(eact), "iconId", "text_word_spacing", NULL ); } /* Letter spacing */ @@ -7423,8 +7700,8 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions "TextLetterSpacingAction", /* name */ _("Letter spacing"), /* label */ _("Letter:"), /* short label */ - _("Spacing between letters."), /* tooltip */ - "/tools/text/letterspacing", /* path? */ + _("Spacing between letters (px)"), /* tooltip */ + "/tools/text/letterspacing", /* preferences path */ 0.0, /* default */ GTK_WIDGET(desktop->canvas), /* focusTarget */ NULL, /* unit selector */ @@ -7441,6 +7718,100 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); g_object_set_data( holder, "TextLetterSpacingAction", eact ); + g_object_set( G_OBJECT(eact), "iconId", "text_letter_spacing", NULL ); + } + + /* Character kerning (horizontal shift) */ + { + // Drop down menu + gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + gdouble values[] = { -2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5 }; + + EgeAdjustmentAction *eact = create_adjustment_action( + "TextDxAction", /* name */ + _("Kerning"), /* label */ + _("Kern:"), /* short label */ + _("Horizontal kerning (px)"), /* tooltip */ + "/tools/text/dx", /* preferences path */ + 0.0, /* default */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + NULL, /* unit selector */ + holder, /* dataKludge */ + FALSE, /* set alt-x keyboard shortcut? */ + NULL, /* altx_mark */ + -100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */ + labels, values, G_N_ELEMENTS(labels), /* drop down menu */ + sp_text_dx_value_changed, /* callback */ + 0.1, /* step (used?) */ + 2, /* digits to show */ + 1.0 /* factor (multiplies default) */ + ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + g_object_set_data( holder, "TextDxAction", eact ); + g_object_set( G_OBJECT(eact), "iconId", "text_horz_kern", NULL ); + } + + /* Character vertical shift */ + { + // Drop down menu + gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + gdouble values[] = { -2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5 }; + + EgeAdjustmentAction *eact = create_adjustment_action( + "TextDyAction", /* name */ + _("Vertical Shift"), /* label */ + _("Vert:"), /* short label */ + _("Vertical shift (px)"), /* tooltip */ + "/tools/text/dy", /* preferences path */ + 0.0, /* default */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + NULL, /* unit selector */ + holder, /* dataKludge */ + FALSE, /* set alt-x keyboard shortcut? */ + NULL, /* altx_mark */ + -100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */ + labels, values, G_N_ELEMENTS(labels), /* drop down menu */ + sp_text_dy_value_changed, /* callback */ + 0.1, /* step (used?) */ + 2, /* digits to show */ + 1.0 /* factor (multiplies default) */ + ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + g_object_set_data( holder, "TextDyAction", eact ); + g_object_set( G_OBJECT(eact), "iconId", "text_vert_kern", NULL ); + } + + /* Character rotation */ + { + // Drop down menu + gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + gdouble values[] = { -90, -45, -30, -15, 0, 15, 30, 45, 90, 180 }; + + EgeAdjustmentAction *eact = create_adjustment_action( + "TextRotationAction", /* name */ + _("Letter rotation"), /* label */ + _("Rot:"), /* short label */ + _("Character rotation (degrees)"),/* tooltip */ + "/tools/text/rotation", /* preferences path */ + 0.0, /* default */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + NULL, /* unit selector */ + holder, /* dataKludge */ + FALSE, /* set alt-x keyboard shortcut? */ + NULL, /* altx_mark */ + -180.0, 180.0, 0.1, 1.0, /* lower, upper, step (arrow up/down), page up/down */ + labels, values, G_N_ELEMENTS(labels), /* drop down menu */ + sp_text_rotation_value_changed, /* callback */ + 0.1, /* step (used?) */ + 2, /* digits to show */ + 1.0 /* factor (multiplies default) */ + ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + g_object_set_data( holder, "TextRotationAction", eact ); + g_object_set( G_OBJECT(eact), "iconId", "text_rotation", NULL ); } // Is this necessary to call? Shouldn't hurt. |
