diff options
| author | Michael Soegtrop <MSoegtrop@yahoo.de> | 2017-06-05 13:01:17 +0000 |
|---|---|---|
| committer | Michael Soegtrop <MSoegtrop@yahoo.de> | 2017-06-05 13:01:17 +0000 |
| commit | e7248b2fa042f42a5c4dd14cd86ab6a5b4524059 (patch) | |
| tree | 9097520c54e355ded9bd0b4d6618af4e8dacdd91 /src/widgets | |
| parent | updated to latest trunk (diff) | |
| parent | [Bug #1695016] Xaml export misses some radialGradients. (diff) | |
| download | inkscape-e7248b2fa042f42a5c4dd14cd86ab6a5b4524059.tar.gz inkscape-e7248b2fa042f42a5c4dd14cd86ab6a5b4524059.zip | |
updated to latest trunk
(bzr r14876.2.4)
Diffstat (limited to 'src/widgets')
77 files changed, 5179 insertions, 3832 deletions
diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index 225afe317..1184291f2 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -1,31 +1,20 @@ +add_subdirectory(gimp) set(widgets_SRC + arc-toolbar.cpp + box3d-toolbar.cpp button.cpp - arc-toolbar.cpp - box3d-toolbar.cpp - calligraphy-toolbar.cpp - connector-toolbar.cpp - dropper-toolbar.cpp - eraser-toolbar.cpp - lpe-toolbar.cpp - measure-toolbar.cpp - mesh-toolbar.cpp - node-toolbar.cpp - pencil-toolbar.cpp - rect-toolbar.cpp - spiral-toolbar.cpp - spray-toolbar.cpp - star-toolbar.cpp - text-toolbar.cpp - tweak-toolbar.cpp - zoom-toolbar.cpp + calligraphy-toolbar.cpp + connector-toolbar.cpp dash-selector.cpp desktop-widget.cpp + dropper-toolbar.cpp eek-preview.cpp + ege-adjustment-action.cpp + ege-output-action.cpp ege-paint-def.cpp - ege-adjustment-action.cpp - ege-output-action.cpp - ege-select-one-action.cpp + ege-select-one-action.cpp + eraser-toolbar.cpp fill-style.cpp font-selector.cpp gradient-image.cpp @@ -35,8 +24,16 @@ set(widgets_SRC icon.cpp ink-action.cpp ink-comboboxentry-action.cpp + ink-radio-action.cpp + ink-toggle-action.cpp + ink-tool-menu-action.cpp + lpe-toolbar.cpp + measure-toolbar.cpp + mesh-toolbar.cpp + node-toolbar.cpp paint-selector.cpp - ruler.cpp + pencil-toolbar.cpp + rect-toolbar.cpp select-toolbar.cpp sp-attribute-widget.cpp sp-color-selector.cpp @@ -45,41 +42,35 @@ set(widgets_SRC sp-xmlview-content.cpp sp-xmlview-tree.cpp spinbutton-events.cpp + spiral-toolbar.cpp + spray-toolbar.cpp spw-utilities.cpp + star-toolbar.cpp stroke-marker-selector.cpp stroke-style.cpp swatch-selector.cpp + text-toolbar.cpp toolbox.cpp + tweak-toolbar.cpp + zoom-toolbar.cpp # ------- # Headers + arc-toolbar.h + box3d-toolbar.h button.h - arc-toolbar.h - box3d-toolbar.h - calligraphy-toolbar.h - connector-toolbar.h - dropper-toolbar.h - eraser-toolbar.h - lpe-toolbar.h - measure-toolbar.h - mesh-toolbar.h - node-toolbar.h - pencil-toolbar.h - rect-toolbar.h - spiral-toolbar.h - spray-toolbar.h - star-toolbar.h - text-toolbar.h - tweak-toolbar.h - zoom-toolbar.h + calligraphy-toolbar.h + connector-toolbar.h dash-selector.h desktop-widget.h + dropper-toolbar.h eek-preview.h + ege-adjustment-action.h + ege-output-action.h ege-paint-def.h - ege-adjustment-action.h - ege-output-action.h - ege-select-one-action.h + ege-select-one-action.h + eraser-toolbar.h fill-n-stroke-factory.h fill-style.h font-selector.h @@ -88,10 +79,18 @@ set(widgets_SRC gradient-toolbar.h gradient-vector.h icon.h - ink-action.h - ink-comboboxentry-action.h + ink-action.h + ink-comboboxentry-action.h + ink-radio-action.h + ink-toggle-action.h + ink-tool-menu-action.h + lpe-toolbar.h + measure-toolbar.h + mesh-toolbar.h + node-toolbar.h paint-selector.h - ruler.h + pencil-toolbar.h + rect-toolbar.h select-toolbar.h sp-attribute-widget.h sp-color-selector.h @@ -100,30 +99,29 @@ set(widgets_SRC sp-xmlview-content.h sp-xmlview-tree.h spinbutton-events.h + spiral-toolbar.h + spray-toolbar.h spw-utilities.h + star-toolbar.h stroke-marker-selector.h stroke-style.h swatch-selector.h + text-toolbar.h toolbox.h + tweak-toolbar.h widget-sizes.h + zoom-toolbar.h ) -if(${WITH_GTK3_EXPERIMENTAL}) - set(image_menu_item_SRC image-menu-item.h image-menu-item.c) - add_inkscape_source("${image_menu_item_SRC}") -endif() - # add_inkscape_lib(widgets_LIB "${widgets_SRC}") add_inkscape_source("${widgets_SRC}") -set ( widgets_paintbucket_SRC - paintbucket-toolbar.cpp - paintbucket-toolbar.h +set(widgets_paintbucket_SRC + paintbucket-toolbar.cpp + paintbucket-toolbar.h ) if ("${HAVE_POTRACE}") add_inkscape_source("${widgets_paintbucket_SRC}") endif() - - diff --git a/src/widgets/Makefile_insert b/src/widgets/Makefile_insert deleted file mode 100644 index c9f04de14..000000000 --- a/src/widgets/Makefile_insert +++ /dev/null @@ -1,123 +0,0 @@ -## Makefile.am fragment sourced by src/Makefile.am. - -if WITH_GTKMM_3_0 -ink_common_sources += \ - widgets/image-menu-item.c \ - widgets/image-menu-item.h -endif - -ink_common_sources += \ - widgets/arc-toolbar.cpp \ - widgets/arc-toolbar.h \ - widgets/box3d-toolbar.cpp \ - widgets/box3d-toolbar.h \ - widgets/button.cpp \ - widgets/button.h \ - widgets/calligraphy-toolbar.cpp \ - widgets/calligraphy-toolbar.h \ - widgets/connector-toolbar.cpp \ - widgets/connector-toolbar.h \ - widgets/dash-selector.cpp \ - widgets/dash-selector.h \ - widgets/desktop-widget.cpp \ - widgets/desktop-widget.h \ - widgets/dropper-toolbar.cpp \ - widgets/dropper-toolbar.h \ - widgets/eek-preview.cpp \ - widgets/eek-preview.h \ - widgets/ege-adjustment-action.cpp \ - widgets/ege-adjustment-action.h \ - widgets/ege-paint-def.cpp \ - widgets/ege-paint-def.h \ - widgets/ege-output-action.cpp \ - widgets/ege-output-action.h \ - widgets/ege-select-one-action.cpp \ - widgets/ege-select-one-action.h \ - widgets/eraser-toolbar.cpp \ - widgets/eraser-toolbar.h \ - widgets/fill-style.cpp \ - widgets/fill-style.h \ - widgets/fill-n-stroke-factory.h \ - widgets/font-selector.cpp \ - widgets/font-selector.h \ - widgets/gradient-image.cpp \ - widgets/gradient-image.h \ - widgets/gradient-selector.cpp \ - widgets/gradient-selector.h \ - widgets/gradient-toolbar.cpp \ - widgets/gradient-toolbar.h \ - widgets/gradient-vector.cpp \ - widgets/gradient-vector.h \ - widgets/icon.cpp \ - widgets/icon.h \ - widgets/ink-action.cpp \ - widgets/ink-action.h \ - widgets/ink-comboboxentry-action.cpp \ - widgets/ink-comboboxentry-action.h \ - widgets/lpe-toolbar.cpp \ - widgets/lpe-toolbar.h \ - widgets/measure-toolbar.cpp \ - widgets/measure-toolbar.h \ - widgets/mesh-toolbar.cpp \ - widgets/mesh-toolbar.h \ - widgets/node-toolbar.cpp \ - widgets/node-toolbar.h \ - widgets/paint-selector.cpp \ - widgets/paint-selector.h \ - widgets/pencil-toolbar.cpp \ - widgets/pencil-toolbar.h \ - widgets/rect-toolbar.cpp \ - widgets/rect-toolbar.h \ - widgets/ruler.cpp \ - widgets/ruler.h \ - widgets/select-toolbar.cpp \ - widgets/select-toolbar.h \ - widgets/spray-toolbar.cpp \ - widgets/spray-toolbar.h \ - widgets/spiral-toolbar.cpp \ - widgets/spiral-toolbar.h \ - widgets/sp-attribute-widget.cpp \ - widgets/sp-attribute-widget.h \ - widgets/sp-color-selector.cpp \ - widgets/sp-color-selector.h \ - widgets/spinbutton-events.cpp \ - widgets/spinbutton-events.h \ - widgets/sp-widget.cpp \ - widgets/sp-widget.h \ - widgets/spw-utilities.cpp \ - widgets/spw-utilities.h \ - widgets/sp-xmlview-attr-list.cpp \ - widgets/sp-xmlview-attr-list.h \ - widgets/sp-xmlview-content.cpp \ - widgets/sp-xmlview-content.h \ - widgets/sp-xmlview-tree.cpp \ - widgets/sp-xmlview-tree.h \ - widgets/star-toolbar.cpp \ - widgets/star-toolbar.h \ - widgets/stroke-marker-selector.cpp \ - widgets/stroke-marker-selector.h \ - widgets/stroke-style.cpp \ - widgets/stroke-style.h \ - widgets/swatch-selector.cpp \ - widgets/swatch-selector.h \ - widgets/text-toolbar.cpp \ - widgets/text-toolbar.h \ - widgets/toolbox.cpp \ - widgets/toolbox.h \ - widgets/tweak-toolbar.cpp \ - widgets/tweak-toolbar.h \ - widgets/widget-sizes.h \ - widgets/zoom-toolbar.cpp \ - widgets/zoom-toolbar.h \ - widgets/widget-sizes.h - -if HAVE_POTRACE - -ink_common_sources += \ - widgets/paintbucket-toolbar.cpp \ - widgets/paintbucket-toolbar.h - -endif - -widgets/button.$(OBJEXT): helper/sp-marshal.h -widgets/menu.$(OBJEXT): helper/sp-marshal.h diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index 7b872e8b1..56eeb8922 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <glibmm/i18n.h> @@ -37,9 +37,9 @@ #include "widgets/ege-adjustment-action.h" #include "widgets/ege-output-action.h" #include "widgets/ege-select-one-action.h" -#include "widgets/ink-action.h" +#include "ink-action.h" +#include "ink-radio-action.h" #include "mod360.h" -#include "preferences.h" #include "selection.h" #include "sp-ellipse.h" #include "toolbox.h" @@ -49,7 +49,6 @@ #include "verbs.h" #include "widgets/spinbutton-events.h" #include "xml/node-event-vector.h" -#include "xml/repr.h" using Inkscape::UI::UXManager; using Inkscape::DocumentUndo; @@ -97,8 +96,8 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v gchar* namespaced_name = g_strconcat("sodipodi:", value_name, NULL); bool modmade = false; - std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_GENERICELLIPSE(item)) { @@ -149,7 +148,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/shapes/arc/open", ege_select_one_action_get_active(act) != 0); + prefs->setInt("/tools/shapes/arc/arc_type", ege_select_one_action_get_active(act)); } // quit if run by the attr_changed listener @@ -160,35 +159,43 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) // in turn, prevent listener from responding g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - bool modmade = false; - if ( ege_select_one_action_get_active(act) != 0 ) { - std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - if (SP_IS_GENERICELLIPSE(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - repr->setAttribute("sodipodi:open", "true"); - item->updateRepr(); - modmade = true; - } - } - } else { - std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - if (SP_IS_GENERICELLIPSE(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - repr->setAttribute("sodipodi:open", NULL); - item->updateRepr(); - modmade = true; - } + int mode = ege_select_one_action_get_active(act); + Glib::ustring arc_type = "slice"; + bool open = false; + switch (mode) { + case 0: + arc_type = "slice"; + open = false; + break; + case 1: + arc_type = "arc"; + open = true; + break; + case 2: + arc_type = "chord"; + open = true; // For backward compat, not truly open but chord most like arc. + break; + default: + std::cerr << "sp_arctb_open_state_changed: bad arc type: " << mode << std::endl; + } + + bool modmade = false; + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i; + if (SP_IS_GENERICELLIPSE(item)) { + Inkscape::XML::Node *repr = item->getRepr(); + repr->setAttribute("sodipodi:open", (open?"true":NULL) ); + repr->setAttribute("sodipodi:arc-type", arc_type.c_str()); + item->updateRepr(); + modmade = true; } } if (modmade) { DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ARC, - _("Arc: Change open/closed")); + _("Arc: Changed arc type")); } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); @@ -235,14 +242,22 @@ static void arc_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const * / sp_arctb_sensitivize( tbl, gtk_adjustment_get_value(adj1), gtk_adjustment_get_value(adj2) ); - char const *openstr = NULL; - openstr = repr->attribute("sodipodi:open"); + char const *arctypestr = NULL; + arctypestr = repr->attribute("sodipodi:arc-type"); + if (!arctypestr) { // For old files. + char const *openstr = NULL; + openstr = repr->attribute("sodipodi:open"); + arctypestr = (openstr ? "arc" : "slice"); + } + EgeSelectOneAction *ocb = EGE_SELECT_ONE_ACTION( g_object_get_data( tbl, "open_action" ) ); - if (openstr) { + if (!strcmp(arctypestr,"slice")) { + ege_select_one_action_set_active( ocb, 0 ); + } else if (!strcmp(arctypestr,"arc")) { ege_select_one_action_set_active( ocb, 1 ); } else { - ege_select_one_action_set_active( ocb, 0 ); + ege_select_one_action_set_active( ocb, 2 ); } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); @@ -264,8 +279,8 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb purge_repr_listener( tbl, tbl ); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_GENERICELLIPSE(item)) { n_selected++; @@ -339,25 +354,32 @@ void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObjec gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); } - /* Segments / Pie checkbox */ + /* Arc: Slice, Arc, Chord */ { GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); GtkTreeIter iter; gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, - 0, _("Closed arc"), - 1, _("Switch to segment (closed shape with two radii)"), + 0, _("Slice"), + 1, _("Switch to slice (closed shape with two radii)"), 2, INKSCAPE_ICON("draw-ellipse-segment"), -1 ); gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, - 0, _("Open Arc"), + 0, _("Arc (Open)"), 1, _("Switch to arc (unclosed shape)"), 2, INKSCAPE_ICON("draw-ellipse-arc"), -1 ); + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, + 0, _("Chord"), + 1, _("Switch to chord (closed shape)"), + 2, INKSCAPE_ICON("draw-ellipse-chord"), + -1 ); + EgeSelectOneAction* act = ege_select_one_action_new( "ArcOpenAction", (""), (""), NULL, GTK_TREE_MODEL(model) ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); g_object_set_data( holder, "open_action", act ); @@ -369,8 +391,8 @@ void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObjec ege_select_one_action_set_icon_size( act, secondarySize ); ege_select_one_action_set_tooltip_column( act, 1 ); - bool isClosed = !prefs->getBool("/tools/shapes/arc/open", false); - ege_select_one_action_set_active( act, isClosed ? 0 : 1 ); + int arc_type = prefs->getInt("/tools/shapes/arc/arc_type", 0); + ege_select_one_action_set_active( act, arc_type ); g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_arctb_open_state_changed), holder ); } diff --git a/src/widgets/box3d-toolbar.cpp b/src/widgets/box3d-toolbar.cpp index 31b897ced..95de28cf2 100644 --- a/src/widgets/box3d-toolbar.cpp +++ b/src/widgets/box3d-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <glibmm/i18n.h> @@ -37,10 +37,9 @@ #include "document-undo.h" #include "document.h" #include "widgets/ege-adjustment-action.h" -#include "widgets/ink-action.h" +#include "widgets/ink-toggle-action.h" #include "inkscape.h" #include "persp3d.h" -#include "selection.h" #include "toolbox.h" #include "ui/icon-names.h" #include "ui/tools/box3d-tool.h" diff --git a/src/widgets/button.cpp b/src/widgets/button.cpp index 6ea8c1360..485300a25 100644 --- a/src/widgets/button.cpp +++ b/src/widgets/button.cpp @@ -20,18 +20,9 @@ #include "shortcuts.h" #include "helper/action.h" -#include <gdk/gdkkeysyms.h> - static void sp_button_dispose(GObject *object); - -#if GTK_CHECK_VERSION(3, 0, 0) static void sp_button_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width); - static void sp_button_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height); -#else -static void sp_button_size_request(GtkWidget *widget, GtkRequisition *requisition); -#endif - static void sp_button_clicked(GtkButton *button); static void sp_button_perform_action(SPButton *button, gpointer data); static gint sp_button_process_event(SPButton *button, GdkEvent *event); @@ -50,12 +41,8 @@ static void sp_button_class_init(SPButtonClass *klass) GtkButtonClass *button_class = GTK_BUTTON_CLASS(klass); object_class->dispose = sp_button_dispose; -#if GTK_CHECK_VERSION(3, 0, 0) - widget_class->get_preferred_width = sp_button_get_preferred_width; - widget_class->get_preferred_height = sp_button_get_preferred_height; -#else - widget_class->size_request = sp_button_size_request; -#endif + //widget_class->get_preferred_width = sp_button_get_preferred_width; + //widget_class->get_preferred_height = sp_button_get_preferred_height; button_class->clicked = sp_button_clicked; } @@ -92,7 +79,6 @@ static void sp_button_dispose(GObject *object) (G_OBJECT_CLASS(sp_button_parent_class))->dispose(object); } -#if GTK_CHECK_VERSION(3, 0, 0) static void sp_button_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width) { GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget)); @@ -136,23 +122,6 @@ static void sp_button_get_preferred_height(GtkWidget *widget, gint *minimal_heig *minimal_height += MAX(2, padding.top + padding.bottom + border.top + border.bottom); *natural_height += MAX(2, padding.top + padding.bottom + border.top + border.bottom); } -#else -static void sp_button_size_request(GtkWidget *widget, GtkRequisition *requisition) -{ - GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget)); - GtkStyle *style = gtk_widget_get_style(widget); - - if (child) { - gtk_widget_size_request(GTK_WIDGET(child), requisition); - } else { - requisition->width = 0; - requisition->height = 0; - } - - requisition->width += 2 + 2 * MAX(2, style->xthickness); - requisition->height += 2 + 2 * MAX(2, style->ythickness); -} -#endif static void sp_button_clicked(GtkButton *button) { diff --git a/src/widgets/calligraphy-toolbar.cpp b/src/widgets/calligraphy-toolbar.cpp index 4ae6427ad..031295ccd 100644 --- a/src/widgets/calligraphy-toolbar.cpp +++ b/src/widgets/calligraphy-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include "ui/dialog/calligraphic-profile-rename.h" @@ -37,7 +37,7 @@ #include "widgets/ege-adjustment-action.h" #include "widgets/ege-select-one-action.h" #include "widgets/ink-action.h" -#include "preferences.h" +#include "widgets/ink-toggle-action.h" #include "toolbox.h" #include "ui/icon-names.h" #include "ui/uxmanager.h" diff --git a/src/widgets/connector-toolbar.cpp b/src/widgets/connector-toolbar.cpp index 733fb34e8..a078ecec4 100644 --- a/src/widgets/connector-toolbar.cpp +++ b/src/widgets/connector-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <glibmm/i18n.h> @@ -38,12 +38,10 @@ #include "widgets/ege-adjustment-action.h" #include "enums.h" #include "graphlayout.h" -#include "widgets/ink-action.h" +#include "ink-action.h" +#include "ink-toggle-action.h" #include "inkscape.h" -#include "preferences.h" -#include "selection.h" #include "sp-namedview.h" -#include "sp-path.h" #include "toolbox.h" #include "ui/icon-names.h" #include "ui/tools/connector-tool.h" @@ -51,7 +49,6 @@ #include "verbs.h" #include "widgets/spinbutton-events.h" #include "xml/node-event-vector.h" -#include "xml/repr.h" using Inkscape::UI::UXManager; using Inkscape::DocumentUndo; @@ -97,8 +94,8 @@ static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl gchar *value = is_orthog ? orthog_str : polyline_str ; bool modmade = false; - std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (Inkscape::UI::Tools::cc_item_is_connector(item)) { @@ -144,8 +141,8 @@ static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) g_ascii_dtostr(value, G_ASCII_DTOSTR_BUF_SIZE, newValue); bool modmade = false; - std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (Inkscape::UI::Tools::cc_item_is_connector(item)) { @@ -227,7 +224,9 @@ static void sp_connector_graph_layout(void) int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - graphlayout(SP_ACTIVE_DESKTOP->getSelection()->itemList()); + auto tmp = SP_ACTIVE_DESKTOP->getSelection()->items(); + std::vector<SPItem *> vec(tmp.begin(), tmp.end()); + graphlayout(vec); prefs->setInt("/options/clonecompensation/value", saved_compensation); diff --git a/src/widgets/dash-selector.cpp b/src/widgets/dash-selector.cpp index 9d591d33d..05f3ab44c 100644 --- a/src/widgets/dash-selector.cpp +++ b/src/widgets/dash-selector.cpp @@ -13,15 +13,13 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include "dash-selector.h" #include <cstring> -#include <string> #include <glibmm/i18n.h> -#include <gtkmm/adjustment.h> #include <2geom/coord.h> #include "style.h" @@ -61,18 +59,9 @@ SPDashSelector::SPDashSelector() dash_combo.signal_changed().connect( sigc::mem_fun(*this, &SPDashSelector::on_selection) ); this->pack_start(dash_combo, false, false, 0); - -#if WITH_GTKMM_3_0 offset = Gtk::Adjustment::create(0.0, 0.0, 10.0, 0.1, 1.0, 0.0); -#else - offset = new Gtk::Adjustment(0.0, 0.0, 10.0, 0.1, 1.0, 0.0); -#endif offset->signal_value_changed().connect(sigc::mem_fun(*this, &SPDashSelector::offset_value_changed)); -#if WITH_GTKMM_3_0 - Inkscape::UI::Widget::SpinButton *sb = new Inkscape::UI::Widget::SpinButton(offset, 0.1, 2); -#else - Inkscape::UI::Widget::SpinButton *sb = new Inkscape::UI::Widget::SpinButton(*offset, 0.1, 2); -#endif + auto sb = new Inkscape::UI::Widget::SpinButton(offset, 0.1, 2); sb->set_tooltip_text(_("Pattern offset")); sp_dialog_defocus_on_enter_cpp(sb); sb->show(); @@ -99,9 +88,6 @@ SPDashSelector::SPDashSelector() SPDashSelector::~SPDashSelector() { // FIXME: for some reason this doesn't get called; does the call to manage() in // sp_stroke_style_line_widget_new() not processed correctly? -#if !WITH_GTKMM_3_0 - delete offset; -#endif } void SPDashSelector::prepareImageRenderer( Gtk::TreeModel::const_iterator const &row ) { @@ -188,11 +174,13 @@ void SPDashSelector::set_dash (int ndash, double *dash, double o) else if(ndash==0) { pos = 0; } - if(pos>=0){ this->set_data("pattern", dashes[pos]); this->dash_combo.set_active(pos); this->offset->set_value(o); + if(pos == 10) { + this->offset->set_value(10.0); + } } else { // Hit a custom pattern in the SVG, write it into the combobox. count--; // the one slot for custom patterns diff --git a/src/widgets/dash-selector.h b/src/widgets/dash-selector.h index ec5a1cbd5..f176acf04 100644 --- a/src/widgets/dash-selector.h +++ b/src/widgets/dash-selector.h @@ -85,12 +85,7 @@ private: Glib::RefPtr<Gtk::ListStore> dash_store; Gtk::ComboBox dash_combo; Gtk::CellRendererPixbuf image_renderer; - -#if WITH_GTKMM_3_0 Glib::RefPtr<Gtk::Adjustment> offset; -#else - Gtk::Adjustment *offset; -#endif static gchar const *const _prefs_path; int preview_width; diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 164a06910..d8c27f5b7 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -36,21 +36,15 @@ #include "desktop-widget.h" #include "display/sp-canvas.h" #include "display/canvas-arena.h" -#include "document.h" #include "ege-color-prof-tracker.h" #include "widgets/ege-select-one-action.h" #include <extension/db.h> #include "file.h" #include "helper/action.h" -#include "helper/action-context.h" #include "util/units.h" #include "ui/widget/unit-tracker.h" -#include "inkscape.h" #include "ui/interface.h" -#include "macros.h" -#include "preferences.h" #include "sp-image.h" -#include "sp-item.h" #include "sp-namedview.h" #include "ui/dialog/swatches.h" #include "ui/icon-names.h" @@ -60,43 +54,25 @@ #include "ui/uxmanager.h" #include "util/ege-appear-time-tracker.h" #include "sp-root.h" - +#include "attributes.h" // We're in the "widgets" directory, so no need to explicitly prefix these: #include "button.h" -#include "ruler.h" +#include "gimp/ruler.h" #include "spinbutton-events.h" #include "spw-utilities.h" #include "toolbox.h" #include "widget-sizes.h" - #include "verbs.h" -#if GTK_CHECK_VERSION(3,0,0) -# include <gtkmm/cssprovider.h> -#endif +#include <gtkmm/cssprovider.h> #include <gtkmm/paned.h> #include <gtkmm/messagedialog.h> -#include <gtk/gtk.h> - -#if defined (SOLARIS) && (SOLARIS == 8) -#include "round.h" -using Inkscape::round; -#endif - using Inkscape::UI::Widget::UnitTracker; using Inkscape::UI::UXManager; using Inkscape::UI::ToolboxFactory; using ege::AppearTimeTracker; using Inkscape::Util::unit_table; -enum { - ACTIVATE, - DEACTIVATE, - MODIFIED, - EVENT_CONTEXT_CHANGED, - LAST_SIGNAL -}; - //--------------------------------------------------------------------- /* SPDesktopWidget */ @@ -124,14 +100,13 @@ static bool sp_dtw_zoom_output (GtkSpinButton *spin, gpointer data); static void sp_dtw_zoom_value_changed (GtkSpinButton *spin, gpointer data); static void sp_dtw_zoom_populate_popup (GtkEntry *entry, GtkMenu *menu, gpointer data); static void sp_dtw_zoom_menu_handler (SPDesktop *dt, gdouble factor); -static void sp_dtw_zoom_50 (GtkMenuItem *item, gpointer data); -static void sp_dtw_zoom_100 (GtkMenuItem *item, gpointer data); -static void sp_dtw_zoom_200 (GtkMenuItem *item, gpointer data); -static void sp_dtw_zoom_page (GtkMenuItem *item, gpointer data); -static void sp_dtw_zoom_drawing (GtkMenuItem *item, gpointer data); -static void sp_dtw_zoom_selection (GtkMenuItem *item, gpointer data); static void sp_dtw_sticky_zoom_toggled (GtkMenuItem *item, gpointer data); +static gint sp_dtw_rotation_input (GtkSpinButton *spin, gdouble *new_val, gpointer data); +static bool sp_dtw_rotation_output (GtkSpinButton *spin, gpointer data); +static void sp_dtw_rotation_value_changed (GtkSpinButton *spin, gpointer data); +static void sp_dtw_rotation_populate_popup (GtkEntry *entry, GtkMenu *menu, gpointer data); + SPViewWidgetClass *dtw_parent_class; class CMSPrefWatcher { @@ -256,16 +231,11 @@ Geom::Point SPDesktopWidget::window_get_pointer() { gint x,y; - GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(canvas)); - -#if GTK_CHECK_VERSION(3,0,0) - GdkDisplay *display = gdk_window_get_display(window); - GdkDeviceManager *dm = gdk_display_get_device_manager(display); - GdkDevice *device = gdk_device_manager_get_client_pointer(dm); + auto window = gtk_widget_get_window(GTK_WIDGET(canvas)); + auto display = gdk_window_get_display(window); + auto dm = gdk_display_get_device_manager(display); + auto device = gdk_device_manager_get_client_pointer(dm); gdk_window_get_device_position(window, device, &x, &y, NULL); -#else - gdk_window_get_pointer(window, &x, &y, NULL); -#endif return Geom::Point(x,y); } @@ -322,7 +292,7 @@ sp_desktop_widget_class_init (SPDesktopWidgetClass *klass) * This adjusts the range of the rulers when the dock container is adjusted * (fixes lp:950552) */ -static void canvas_tbl_size_allocate(GtkWidget * /*widget*/, +static void canvas_tbl_size_allocate(GtkWidget * widget, GdkRectangle * /*allocation*/, gpointer data) { @@ -344,21 +314,11 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) dtw->_interaction_disabled_counter = 0; /* Main table */ -#if GTK_CHECK_VERSION(3,0,0) dtw->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_widget_set_name(dtw->vbox, "DesktopMainTable"); -#else - dtw->vbox = gtk_vbox_new (FALSE, 0); -#endif gtk_container_add( GTK_CONTAINER(dtw), GTK_WIDGET(dtw->vbox) ); - -#if GTK_CHECK_VERSION(3,0,0) dtw->statusbar = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_widget_set_name(dtw->statusbar, "DesktopStatusBar"); -#else - dtw->statusbar = gtk_hbox_new (FALSE, 0); -#endif - //gtk_widget_set_usize (dtw->statusbar, -1, BOTTOM_BAR_HEIGHT); gtk_box_pack_end (GTK_BOX (dtw->vbox), dtw->statusbar, FALSE, TRUE, 0); { @@ -366,19 +326,12 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) dtw->panels = new SwatchesPanel("/embedded/swatches" /*false*/); dtw->panels->setOrientation(SP_ANCHOR_SOUTH); -#if GTK_CHECK_VERSION(3,0,0) dtw->panels->set_vexpand(false); -#endif - gtk_box_pack_end( GTK_BOX( dtw->vbox ), GTK_WIDGET(dtw->panels->gobj()), FALSE, TRUE, 0 ); } -#if GTK_CHECK_VERSION(3,0,0) dtw->hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_widget_set_name(dtw->hbox, "DesktopHbox"); -#else - dtw->hbox = gtk_hbox_new(FALSE, 0); -#endif gtk_box_pack_end( GTK_BOX (dtw->vbox), dtw->hbox, TRUE, TRUE, 0 ); gtk_widget_show(dtw->hbox); @@ -402,14 +355,12 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) NULL, INKSCAPE_ICON("object-locked"), _("Toggle lock of all guides in the document")); -#if GTK_CHECK_VERSION(3,0,0) - Glib::RefPtr<Gtk::CssProvider> guides_lock_style_provider = Gtk::CssProvider::create(); + auto guides_lock_style_provider = Gtk::CssProvider::create(); guides_lock_style_provider->load_from_data("GtkWidget { padding-left: 0; padding-right: 0; padding-top: 0; padding-bottom: 0; }"); - Gtk::Widget * wnd = Glib::wrap(dtw->guides_lock); + auto wnd = Glib::wrap(dtw->guides_lock); wnd->set_name("LockGuides"); - Glib::RefPtr<Gtk::StyleContext> context = wnd->get_style_context(); + auto context = wnd->get_style_context(); context->add_provider(guides_lock_style_provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); -#endif /* Horizontal ruler */ GtkWidget *eventbox = gtk_event_box_new (); @@ -424,29 +375,13 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) g_signal_connect (G_OBJECT (eventbox), "button_release_event", G_CALLBACK (sp_dt_hruler_event), dtw); g_signal_connect (G_OBJECT (eventbox), "motion_notify_event", G_CALLBACK (sp_dt_hruler_event), dtw); -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *tbl_wrapper = gtk_grid_new(); // Is this widget really needed? + auto tbl_wrapper = gtk_grid_new(); // Is this widget really needed? gtk_widget_set_name(tbl_wrapper, "CanvasTableWrapper"); dtw->canvas_tbl = gtk_grid_new(); gtk_widget_set_name(dtw->canvas_tbl, "CanvasTable"); gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), dtw->guides_lock, 0, 0, 1, 1); gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), eventbox, 1, 0, 1, 1); -#else - GtkWidget *tbl_wrapper = gtk_table_new(2, 3, FALSE); - dtw->canvas_tbl = gtk_table_new(3, 3, FALSE); - - gtk_table_attach(GTK_TABLE(dtw->canvas_tbl), - dtw->guides_lock, - 0, 1, 0, 1, - GTK_FILL, GTK_FILL, - 0, 0); - gtk_table_attach(GTK_TABLE(dtw->canvas_tbl), - eventbox, - 1, 2, 0, 1, - GTK_FILL, GTK_FILL, - 0, 0); -#endif g_signal_connect (G_OBJECT (dtw->guides_lock), "toggled", G_CALLBACK (sp_update_guides_lock), dtw); gtk_box_pack_start( GTK_BOX(dtw->hbox), tbl_wrapper, TRUE, TRUE, 1 ); @@ -460,16 +395,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) sp_ruler_set_unit (SP_RULER (dtw->vruler), pt); gtk_widget_set_tooltip_text (dtw->vruler_box, gettext(pt->name_plural.c_str())); gtk_container_add (GTK_CONTAINER (eventbox), GTK_WIDGET (dtw->vruler)); - -#if GTK_CHECK_VERSION(3,0,0) gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), eventbox, 0, 1, 1, 1); -#else - gtk_table_attach(GTK_TABLE (dtw->canvas_tbl), - eventbox, - 0, 1, 1, 2, - GTK_FILL, GTK_FILL, - 0, 0); -#endif g_signal_connect (G_OBJECT (eventbox), "button_press_event", G_CALLBACK (sp_dt_vruler_event), dtw); g_signal_connect (G_OBJECT (eventbox), "button_release_event", G_CALLBACK (sp_dt_vruler_event), dtw); @@ -477,19 +403,10 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) // Horizontal scrollbar dtw->hadj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, -4000.0, 4000.0, 10.0, 100.0, 4.0)); - -#if GTK_CHECK_VERSION(3,0,0) dtw->hscrollbar = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (dtw->hadj)); gtk_widget_set_name(dtw->hscrollbar, "HorizontalScrollbar"); gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), dtw->hscrollbar, 1, 2, 1, 1); dtw->vscrollbar_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); -#else - dtw->hscrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (dtw->hadj)); - gtk_table_attach(GTK_TABLE (dtw->canvas_tbl), dtw->hscrollbar, 1, 2, 2, 3, - GTK_FILL, GTK_SHRINK, - 0, 0); - dtw->vscrollbar_box = gtk_vbox_new (FALSE, 0); -#endif // Sticky zoom button dtw->sticky_zoom = sp_button_new_from_data ( Inkscape::ICON_SIZE_DECORATION, @@ -504,23 +421,10 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) // Vertical scrollbar dtw->vadj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, -4000.0, 4000.0, 10.0, 100.0, 4.0)); - -#if GTK_CHECK_VERSION(3,0,0) dtw->vscrollbar = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT(dtw->vadj)); gtk_widget_set_name(dtw->vscrollbar, "VerticalScrollbar"); -#else - dtw->vscrollbar = gtk_vscrollbar_new (GTK_ADJUSTMENT (dtw->vadj)); -#endif - gtk_box_pack_start (GTK_BOX (dtw->vscrollbar_box), dtw->vscrollbar, TRUE, TRUE, 0); - -#if GTK_CHECK_VERSION(3,0,0) gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), dtw->vscrollbar_box, 2, 0, 1, 2); -#else - gtk_table_attach(GTK_TABLE(dtw->canvas_tbl), dtw->vscrollbar_box, 2, 3, 0, 2, - GTK_SHRINK, GTK_FILL, - 0, 0); -#endif gchar const* tip = ""; Inkscape::Verb* verb = Inkscape::Verb::get( SP_VERB_VIEW_CMS_TOGGLE ); @@ -554,15 +458,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) cms_adjust_set_sensitive(dtw, FALSE); #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) -#if GTK_CHECK_VERSION(3,0,0) gtk_grid_attach( GTK_GRID(dtw->canvas_tbl), dtw->cms_adjust, 2, 2, 1, 1); -#else - gtk_table_attach( GTK_TABLE(dtw->canvas_tbl), dtw->cms_adjust, 2, 3, 2, 3, - (GtkAttachOptions)(GTK_SHRINK), - (GtkAttachOptions)(GTK_SHRINK), - 0, 0); -#endif - { if (!watcher) { watcher = new CMSPrefWatcher(); @@ -579,10 +475,8 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) sp_ruler_add_track_widget (SP_RULER(dtw->hruler), GTK_WIDGET(dtw->canvas)); sp_ruler_add_track_widget (SP_RULER(dtw->vruler), GTK_WIDGET(dtw->canvas)); - -#if GTK_CHECK_VERSION(3,0,0) - GtkCssProvider *css_provider = gtk_css_provider_new(); - GtkStyleContext *style_context = gtk_widget_get_style_context(GTK_WIDGET(dtw->canvas)); + auto css_provider = gtk_css_provider_new(); + auto style_context = gtk_widget_get_style_context(GTK_WIDGET(dtw->canvas)); gtk_css_provider_load_from_data(css_provider, "SPCanvas {\n" @@ -593,21 +487,11 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) gtk_style_context_add_provider(style_context, GTK_STYLE_PROVIDER(css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER); -#else - GtkStyle *style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(dtw->canvas))); - style->bg[GTK_STATE_NORMAL] = style->white; - gtk_widget_set_style (GTK_WIDGET (dtw->canvas), style); -#endif - g_signal_connect (G_OBJECT (dtw->canvas), "event", G_CALLBACK (sp_desktop_widget_event), dtw); -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_hexpand(GTK_WIDGET(dtw->canvas), TRUE); gtk_widget_set_vexpand(GTK_WIDGET(dtw->canvas), TRUE); gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), GTK_WIDGET(dtw->canvas), 1, 1, 1, 1); -#else - gtk_table_attach (GTK_TABLE (dtw->canvas_tbl), GTK_WIDGET(dtw->canvas), 1, 2, 1, 2, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), 0, 0); -#endif /* Dock */ bool create_dock = @@ -616,12 +500,8 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) if (create_dock) { dtw->dock = new Inkscape::UI::Widget::Dock(); -#if WITH_GTKMM_3_0 - Gtk::Paned *paned = new Gtk::Paned(); + auto paned = new Gtk::Paned(); paned->set_name("Canvas_and_Dock"); -#else - Gtk::HPaned *paned = new Gtk::HPaned(); -#endif paned->pack1(*Glib::wrap(dtw->canvas_tbl)); paned->pack2(dtw->dock->getWidget(), Gtk::FILL); @@ -632,24 +512,13 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) paned_class->cycle_handle_focus = NULL; } -#if GTK_CHECK_VERSION(3,0,0) - gtk_widget_set_hexpand(GTK_WIDGET(paned->gobj()), TRUE); - gtk_widget_set_vexpand(GTK_WIDGET(paned->gobj()), TRUE); + paned->set_hexpand(true); + paned->set_vexpand(true); gtk_grid_attach(GTK_GRID(tbl_wrapper), GTK_WIDGET (paned->gobj()), 1, 1, 1, 1); -#else - gtk_table_attach (GTK_TABLE (tbl_wrapper), GTK_WIDGET (paned->gobj()), 1, 2, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), - (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0); -#endif - } else { -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_hexpand(GTK_WIDGET(dtw->canvas_tbl), TRUE); gtk_widget_set_vexpand(GTK_WIDGET(dtw->canvas_tbl), TRUE); gtk_grid_attach(GTK_GRID(tbl_wrapper), GTK_WIDGET (dtw->canvas_tbl), 1, 1, 1, 1); -#else - gtk_table_attach (GTK_TABLE (tbl_wrapper), GTK_WIDGET (dtw->canvas_tbl), 1, 2, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), - (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0); -#endif } // connect scrollbar signals @@ -666,11 +535,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) // Separator gtk_box_pack_start(GTK_BOX(dtw->statusbar), -#if GTK_CHECK_VERSION(3,0,0) gtk_separator_new(GTK_ORIENTATION_VERTICAL), -#else - gtk_vseparator_new(), -#endif FALSE, FALSE, 0); // Layer Selector @@ -689,12 +554,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) gtk_label_set_lines (GTK_LABEL(dtw->select_status), 2); #endif -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_halign(dtw->select_status, GTK_ALIGN_START); -#else - gtk_misc_set_alignment (GTK_MISC (dtw->select_status), 0.0, 0.5); -#endif - gtk_widget_set_size_request (dtw->select_status, 1, -1); // Display the initial welcome message in the statusbar @@ -703,82 +563,93 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) gtk_box_pack_start (GTK_BOX (dtw->statusbar), dtw->select_status, TRUE, TRUE, 0); - // Zoom status spinbutton + // Zoom status spinbutton --------------- dtw->zoom_status = gtk_spin_button_new_with_range (log(SP_DESKTOP_ZOOM_MIN)/log(2), log(SP_DESKTOP_ZOOM_MAX)/log(2), 0.1); - gtk_widget_set_name(dtw->zoom_status, "ZoomStatus"); + g_object_set_data (G_OBJECT (dtw->zoom_status), "dtw", dtw->canvas); gtk_widget_set_tooltip_text (dtw->zoom_status, _("Zoom")); gtk_widget_set_size_request (dtw->zoom_status, STATUS_ZOOM_WIDTH, -1); gtk_entry_set_width_chars (GTK_ENTRY (dtw->zoom_status), 6); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (dtw->zoom_status), FALSE); gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (dtw->zoom_status), GTK_UPDATE_ALWAYS); + + // Callbacks g_signal_connect (G_OBJECT (dtw->zoom_status), "input", G_CALLBACK (sp_dtw_zoom_input), dtw); g_signal_connect (G_OBJECT (dtw->zoom_status), "output", G_CALLBACK (sp_dtw_zoom_output), dtw); - g_object_set_data (G_OBJECT (dtw->zoom_status), "dtw", dtw->canvas); g_signal_connect (G_OBJECT (dtw->zoom_status), "focus-in-event", G_CALLBACK (spinbutton_focus_in), dtw->zoom_status); g_signal_connect (G_OBJECT (dtw->zoom_status), "key-press-event", G_CALLBACK (spinbutton_keypress), dtw->zoom_status); dtw->zoom_update = g_signal_connect (G_OBJECT (dtw->zoom_status), "value_changed", G_CALLBACK (sp_dtw_zoom_value_changed), dtw); - dtw->zoom_update = g_signal_connect (G_OBJECT (dtw->zoom_status), "populate_popup", G_CALLBACK (sp_dtw_zoom_populate_popup), dtw); + g_signal_connect (G_OBJECT (dtw->zoom_status), "populate_popup", G_CALLBACK (sp_dtw_zoom_populate_popup), dtw); + + // Style + auto css_provider_spinbutton = Gtk::CssProvider::create(); + css_provider_spinbutton->load_from_data("* { padding-left: 2px; padding-right: 2px; padding-top: 0px; padding-bottom: 0px;}"); // Shouldn't this be in a style sheet? Used also by rotate. + + auto zoomstat = Glib::wrap(dtw->zoom_status); + zoomstat->set_name("ZoomStatus"); + auto context_zoom = zoomstat->get_style_context(); + context_zoom->add_provider(css_provider_spinbutton, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + + // Rotate status spinbutton --------------- + dtw->rotation_status = gtk_spin_button_new_with_range (-360.0,360.0, 1.0); + g_object_set_data (G_OBJECT (dtw->rotation_status), "dtw", dtw->canvas); + gtk_widget_set_tooltip_text (dtw->rotation_status, _("Rotation. (Also Ctrl+Shift+Scroll)")); + gtk_widget_set_size_request (dtw->rotation_status, STATUS_ROTATION_WIDTH, -1); + gtk_entry_set_width_chars (GTK_ENTRY (dtw->rotation_status), 7); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (dtw->rotation_status), FALSE); + gtk_spin_button_set_digits (GTK_SPIN_BUTTON (dtw->rotation_status), 2); + gtk_spin_button_set_increments (GTK_SPIN_BUTTON (dtw->rotation_status), 1.0, 15.0); + gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (dtw->rotation_status), GTK_UPDATE_ALWAYS); + + // Callbacks + g_signal_connect (G_OBJECT (dtw->rotation_status), "input", G_CALLBACK (sp_dtw_rotation_input), dtw); + g_signal_connect (G_OBJECT (dtw->rotation_status), "output", G_CALLBACK (sp_dtw_rotation_output), dtw); + g_signal_connect (G_OBJECT (dtw->rotation_status), "focus-in-event", G_CALLBACK (spinbutton_focus_in), dtw->rotation_status); + g_signal_connect (G_OBJECT (dtw->rotation_status), "key-press-event", G_CALLBACK (spinbutton_keypress), dtw->rotation_status); + dtw->rotation_update = g_signal_connect (G_OBJECT (dtw->rotation_status), "value_changed", G_CALLBACK (sp_dtw_rotation_value_changed), dtw); + g_signal_connect (G_OBJECT (dtw->rotation_status), "populate_popup", G_CALLBACK (sp_dtw_rotation_populate_popup), dtw); + + // Style + auto rotstat = Glib::wrap(dtw->rotation_status); + rotstat->set_name("RotationStatus"); + auto context_rotation = rotstat->get_style_context(); + context_rotation->add_provider(css_provider_spinbutton, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + // Cursor coordinates -#if GTK_CHECK_VERSION(3,0,0) dtw->coord_status = gtk_grid_new(); gtk_widget_set_name(dtw->coord_status, "CoordinateAndZStatus"); gtk_grid_set_row_spacing(GTK_GRID(dtw->coord_status), 0); gtk_grid_set_column_spacing(GTK_GRID(dtw->coord_status), 2); - GtkWidget* sep = gtk_separator_new(GTK_ORIENTATION_VERTICAL); + auto sep = gtk_separator_new(GTK_ORIENTATION_VERTICAL); gtk_widget_set_name(sep, "CoordinateSeparator"); gtk_grid_attach(GTK_GRID(dtw->coord_status), GTK_WIDGET(sep), 0, 0, 1, 2); -#else - dtw->coord_status = gtk_table_new(5, 2, FALSE); - gtk_table_set_row_spacings(GTK_TABLE(dtw->coord_status), 0); - gtk_table_set_col_spacings(GTK_TABLE(dtw->coord_status), 2); - gtk_table_attach(GTK_TABLE(dtw->coord_status), - gtk_vseparator_new(), - 0, 1, 0, 2, - GTK_FILL, GTK_FILL, 0, 0); -#endif gtk_widget_set_tooltip_text (dtw->coord_status, _("Cursor coordinates")); - GtkWidget *label_x = gtk_label_new(_("X:")); - GtkWidget *label_y = gtk_label_new(_("Y:")); - -#if GTK_CHECK_VERSION(3,0,0) + auto label_x = gtk_label_new(_("X:")); + auto label_y = gtk_label_new(_("Y:")); gtk_widget_set_halign(label_x, GTK_ALIGN_START); gtk_widget_set_halign(label_y, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(dtw->coord_status), label_x, 1, 0, 1, 1); gtk_grid_attach(GTK_GRID(dtw->coord_status), label_y, 1, 1, 1, 1); -#else - gtk_misc_set_alignment (GTK_MISC(label_x), 0.0, 0.5); - gtk_misc_set_alignment (GTK_MISC(label_y), 0.0, 0.5); - gtk_table_attach(GTK_TABLE(dtw->coord_status), label_x, 1,2, 0,1, GTK_FILL, GTK_FILL, 0, 0); - gtk_table_attach(GTK_TABLE(dtw->coord_status), label_y, 1,2, 1,2, GTK_FILL, GTK_FILL, 0, 0); -#endif - dtw->coord_status_x = gtk_label_new(NULL); dtw->coord_status_y = gtk_label_new(NULL); gtk_label_set_markup( GTK_LABEL(dtw->coord_status_x), "<tt> 0.00 </tt>" ); gtk_label_set_markup( GTK_LABEL(dtw->coord_status_y), "<tt> 0.00 </tt>" ); - GtkWidget* label_z = gtk_label_new(_("Z:")); + auto label_z = gtk_label_new(_("Z:")); gtk_widget_set_name(label_z, "ZLabel"); - -#if GTK_CHECK_VERSION(3,0,0) + auto label_r = gtk_label_new(_("R:")); + gtk_widget_set_name(label_r, "RLabel"); gtk_widget_set_halign(dtw->coord_status_x, GTK_ALIGN_END); gtk_widget_set_halign(dtw->coord_status_y, GTK_ALIGN_END); gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->coord_status_x, 2, 0, 1, 1); gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->coord_status_y, 2, 1, 1, 1); gtk_grid_attach(GTK_GRID(dtw->coord_status), label_z, 3, 0, 1, 2); + gtk_grid_attach(GTK_GRID(dtw->coord_status), label_r, 5, 0, 1, 2); gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->zoom_status, 4, 0, 1, 2); -#else - gtk_misc_set_alignment (GTK_MISC(dtw->coord_status_x), 1.0, 0.5); - gtk_misc_set_alignment (GTK_MISC(dtw->coord_status_y), 1.0, 0.5); - gtk_table_attach(GTK_TABLE(dtw->coord_status), dtw->coord_status_x, 2,3, 0,1, GTK_FILL, GTK_FILL, 0, 0); - gtk_table_attach(GTK_TABLE(dtw->coord_status), dtw->coord_status_y, 2,3, 1,2, GTK_FILL, GTK_FILL, 0, 0); - gtk_table_attach(GTK_TABLE(dtw->coord_status), label_z, 3,4, 0,2, GTK_FILL, GTK_FILL, 0, 0); - gtk_table_attach(GTK_TABLE(dtw->coord_status), dtw->zoom_status, 4,5, 0,2, GTK_FILL, GTK_FILL, 0, 0); -#endif + gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->rotation_status, 6, 0, 1, 2); sp_set_font_size_smaller (dtw->coord_status); @@ -841,11 +712,22 @@ static void sp_desktop_widget_dispose(GObject *object) if ( watcher ) { watcher->remove(dtw); } + + // Zoom g_signal_handlers_disconnect_by_func(G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK(sp_dtw_zoom_input), dtw); g_signal_handlers_disconnect_by_func(G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK(sp_dtw_zoom_output), dtw); g_signal_handlers_disconnect_matched (G_OBJECT (dtw->zoom_status), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, dtw->zoom_status); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK (sp_dtw_zoom_value_changed), dtw); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK (sp_dtw_zoom_populate_popup), dtw); + + // Rotation + g_signal_handlers_disconnect_by_func(G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK(sp_dtw_rotation_input), dtw); + g_signal_handlers_disconnect_by_func(G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK(sp_dtw_rotation_output), dtw); + g_signal_handlers_disconnect_matched (G_OBJECT (dtw->rotation_status), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, dtw->rotation_status); + g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK (sp_dtw_rotation_value_changed), dtw); + g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK (sp_dtw_rotation_populate_popup), dtw); + + // Canvas g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->canvas), (gpointer) G_CALLBACK (sp_desktop_widget_event), dtw); g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->canvas_tbl), (gpointer) G_CALLBACK (canvas_tbl_size_allocate), dtw); @@ -986,7 +868,7 @@ sp_desktop_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation) double newshortside = MIN(newarea.width(), newarea.height()); zoom *= newshortside / oldshortside; } - dtw->desktop->zoom_absolute(area.midpoint()[Geom::X], area.midpoint()[Geom::Y], zoom); + dtw->desktop->zoom_absolute_center_point (area.midpoint(), zoom); // TODO - Should call show_dialogs() from sp_namedview_window_from_document only. // But delaying the call to here solves dock sizing issues on OS X, (see #171579) @@ -1016,7 +898,7 @@ sp_desktop_widget_realize (GtkWidget *widget) if (d.width() < 1.0 || d.height() < 1.0) return; - dtw->desktop->set_display_area (d.left(), d.top(), d.right(), d.bottom(), 10); + dtw->desktop->set_display_area (d, 10); dtw->updateNamedview(); } @@ -1577,7 +1459,7 @@ void SPDesktopWidget::layoutWidgets() } else { gtk_widget_show_all (dtw->menubar); } - + if (!prefs->getBool(pref_root + "commands/state", true)) { gtk_widget_hide (dtw->commands_toolbox); } else { @@ -1783,8 +1665,8 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) dtw->menubar = sp_ui_main_menubar (dtw->desktop); gtk_widget_set_name(dtw->menubar, "MenuBar"); gtk_widget_show_all (dtw->menubar); + SPNamedView *nv = dtw->desktop->namedview; gtk_box_pack_start (GTK_BOX (dtw->vbox), dtw->menubar, FALSE, FALSE, 0); - dtw->layoutWidgets(); std::vector<GtkWidget *> toolboxes; @@ -1851,9 +1733,16 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) if (GTK_IS_CONTAINER(i->data)) { GList *grch = gtk_container_get_children (GTK_CONTAINER(i->data)); for (GList *j = grch; j != NULL; j = j->next) { + if (!GTK_IS_WIDGET(j->data)) // wasn't a widget continue; + // Don't apply to text toolbar. We want to be able to + // use different units for text. (Bug 1562217) + const gchar* name = gtk_widget_get_name( (GTK_WIDGET(j->data)) ); + if (strcmp( name, "TextToolbar") == 0) + continue; + gpointer t = sp_search_by_data_recursive(GTK_WIDGET(j->data), (gpointer) "tracker"); if (t == NULL) // didn't find any tracker data continue; @@ -1884,15 +1773,9 @@ sp_desktop_widget_adjustment_value_changed (GtkAdjustment */*adj*/, SPDesktopWid dtw->update = 1; - dtw->canvas->scrollTo(gtk_adjustment_get_value(dtw->hadj), - gtk_adjustment_get_value(dtw->vadj), FALSE); - sp_desktop_widget_update_rulers (dtw); - - /* update perspective lines if we are in the 3D box tool (so that infinite ones are shown correctly) */ - //sp_box3d_context_update_lines(dtw->desktop->event_context); - if (SP_IS_BOX3D_CONTEXT(dtw->desktop->event_context)) { - SP_BOX3D_CONTEXT(dtw->desktop->event_context)->_vpdrag->updateLines(); - } + // Do not call canvas->scrollTo directly... messes up 'offset'. + dtw->desktop->scroll_absolute( Geom::Point(gtk_adjustment_get_value(dtw->hadj), + gtk_adjustment_get_value(dtw->vadj)), false); dtw->update = 0; } @@ -1914,6 +1797,7 @@ bool SPDesktopWidget::onFocusInEvent(GdkEventFocus*) return false; } +// ------------------------ Zoom ------------------------ static gdouble sp_dtw_zoom_value_to_display (gdouble value) { @@ -1929,16 +1813,21 @@ sp_dtw_zoom_display_to_value (gdouble value) static gint sp_dtw_zoom_input (GtkSpinButton *spin, gdouble *new_val, gpointer /*data*/) { - gdouble new_scrolled = gtk_spin_button_get_value (spin); - const gchar *b = gtk_entry_get_text (GTK_ENTRY (spin)); - gdouble new_typed = atof (b); + gchar *b = g_strdup (gtk_entry_get_text (GTK_ENTRY (spin))); - if (sp_dtw_zoom_value_to_display (new_scrolled) == new_typed) { // the new value is set by scrolling - *new_val = new_scrolled; - } else { // the new value is typed in - *new_val = sp_dtw_zoom_display_to_value (new_typed); + gchar *comma = g_strstr_len (b, -1, ","); + if (comma) { + *comma = '.'; } + char *oldlocale = g_strdup (setlocale(LC_NUMERIC, NULL)); + setlocale (LC_NUMERIC, "C"); + gdouble new_typed = atof (b); + setlocale (LC_NUMERIC, oldlocale); + g_free (oldlocale); + g_free (b); + + *new_val = sp_dtw_zoom_display_to_value (new_typed); return TRUE; } @@ -1964,15 +1853,24 @@ sp_dtw_zoom_value_changed (GtkSpinButton *spin, gpointer data) SPDesktopWidget *dtw = SP_DESKTOP_WIDGET (data); SPDesktop *desktop = dtw->desktop; - Geom::Rect const d = desktop->get_display_area(); + // Zoom around center of window + Geom::Rect const d_canvas = desktop->getCanvas()->getViewbox(); + Geom::Point midpoint = desktop->w2d(d_canvas.midpoint()); g_signal_handler_block (spin, dtw->zoom_update); - desktop->zoom_absolute (d.midpoint()[Geom::X], d.midpoint()[Geom::Y], zoom_factor); + desktop->zoom_absolute_center_point (midpoint, zoom_factor); g_signal_handler_unblock (spin, dtw->zoom_update); spinbutton_defocus (GTK_WIDGET(spin)); } +static void +sp_dtw_zoom_menu_handler (SPDesktop *dt, gdouble factor) +{ + Geom::Rect const d = dt->get_display_area(); + dt->zoom_absolute_center_point (d.midpoint(), factor); +} +// Zoom Popup Menu static void sp_dtw_zoom_10 (GtkMenuItem */*item*/, gpointer data) { @@ -2036,69 +1934,60 @@ sp_dtw_zoom_selection (GtkMenuItem */*item*/, gpointer data) static void sp_dtw_zoom_populate_popup (GtkEntry */*entry*/, GtkMenu *menu, gpointer data) { - GList *children, *iter; - GtkWidget *item; SPDesktop *dt = SP_DESKTOP_WIDGET (data)->desktop; - children = gtk_container_get_children (GTK_CONTAINER (menu)); - for ( iter = children ; iter ; iter = g_list_next (iter)) { + GList* children = gtk_container_get_children (GTK_CONTAINER (menu)); + for ( auto iter = children ; iter ; iter = g_list_next (iter)) { gtk_container_remove (GTK_CONTAINER (menu), GTK_WIDGET (iter->data)); } g_list_free (children); + GtkWidget *item; + item = gtk_menu_item_new_with_label ("1000%"); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_1000), dt); - gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + item = gtk_menu_item_new_with_label ("500%"); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_500), dt); - gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + item = gtk_menu_item_new_with_label ("200%"); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_200), dt); - gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + item = gtk_menu_item_new_with_label ("100%"); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_100), dt); - gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + item = gtk_menu_item_new_with_label ("50%"); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_50), dt); - gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + item = gtk_menu_item_new_with_label ("25%"); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_25), dt); - gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + item = gtk_menu_item_new_with_label ("10%"); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_10), dt); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); item = gtk_separator_menu_item_new (); - gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); item = gtk_menu_item_new_with_label (_("Page")); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_page), dt); - gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + item = gtk_menu_item_new_with_label (_("Drawing")); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_drawing), dt); - gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + item = gtk_menu_item_new_with_label (_("Selection")); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_selection), dt); - gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); -} -static void -sp_dtw_zoom_menu_handler (SPDesktop *dt, gdouble factor) -{ - Geom::Rect const d = dt->get_display_area(); - dt->zoom_absolute(d.midpoint()[Geom::X], d.midpoint()[Geom::Y], factor); + gtk_widget_show_all (GTK_WIDGET (menu)); } @@ -2116,14 +2005,185 @@ sp_desktop_widget_update_zoom (SPDesktopWidget *dtw) { GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(dtw->zoom_status)); - g_signal_handlers_block_by_func (G_OBJECT (dtw->zoom_status), (gpointer)G_CALLBACK (sp_dtw_zoom_value_changed), dtw); + g_signal_handler_block (G_OBJECT (dtw->zoom_status), dtw->zoom_update); gtk_spin_button_set_value (GTK_SPIN_BUTTON (dtw->zoom_status), log(dtw->desktop->current_zoom()) / log(2)); gtk_widget_queue_draw(GTK_WIDGET(dtw->zoom_status)); if (window) gdk_window_process_updates(window, TRUE); - g_signal_handlers_unblock_by_func (G_OBJECT (dtw->zoom_status), (gpointer)G_CALLBACK (sp_dtw_zoom_value_changed), dtw); + g_signal_handler_unblock (G_OBJECT (dtw->zoom_status), dtw->zoom_update); +} + + +// ---------------------- Rotation ------------------------ +static gint +sp_dtw_rotation_input (GtkSpinButton *spin, gdouble *new_val, gpointer /*data*/) +{ + gchar *b = g_strdup (gtk_entry_get_text (GTK_ENTRY (spin))); + + gchar *comma = g_strstr_len (b, -1, ","); + if (comma) { + *comma = '.'; + } + + char *oldlocale = g_strdup (setlocale(LC_NUMERIC, NULL)); + setlocale (LC_NUMERIC, "C"); + gdouble new_value = atof (b); + setlocale (LC_NUMERIC, oldlocale); + g_free (oldlocale); + g_free (b); + + *new_val = new_value; + return TRUE; +} + +static bool +sp_dtw_rotation_output (GtkSpinButton *spin, gpointer /*data*/) +{ + gchar b[64]; + double val = gtk_spin_button_get_value (spin); + + if (val < -180) val += 360; + if (val > 180) val -= 360; + + g_snprintf (b, 64, "%7.2f°", val); + + gtk_entry_set_text (GTK_ENTRY (spin), b); + return TRUE; +} + +static void +sp_dtw_rotation_value_changed (GtkSpinButton *spin, gpointer data) +{ + double const rotate_factor = M_PI / 180.0 * gtk_spin_button_get_value (spin); + // std::cout << "sp_dtw_rotation_value_changed: " + // << gtk_spin_button_get_value (spin) + // << " (" << rotate_factor << ")" <<std::endl; + + SPDesktopWidget *dtw = SP_DESKTOP_WIDGET (data); + SPDesktop *desktop = dtw->desktop; + + // Rotate around center of window + Geom::Rect const d_canvas = desktop->getCanvas()->getViewbox(); + g_signal_handler_block(spin, dtw->rotation_update); + Geom::Point midpoint = desktop->w2d(d_canvas.midpoint()); + desktop->rotate_absolute_center_point (midpoint, rotate_factor); + g_signal_handler_unblock(spin, dtw->rotation_update); + + spinbutton_defocus (GTK_WIDGET(spin)); +} + +static void +sp_dtw_rotate_minus_135 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), -135); +} + +static void +sp_dtw_rotate_minus_90 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), -90); +} + +static void +sp_dtw_rotate_minus_45 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), -45); +} + +static void +sp_dtw_rotate_0 (GtkMenuItem */*item*/,SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), 0); +} + +static void +sp_dtw_rotate_45 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), 45); +} + +static void +sp_dtw_rotate_90 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), 90); +} + +static void +sp_dtw_rotate_135 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status), 135); +} + +static void +sp_dtw_rotate_180 (GtkMenuItem */*item*/, SPDesktopWidget * data) +{ + gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status),180); +} + +static void +sp_dtw_rotation_populate_popup (GtkEntry */*entry*/, GtkMenu *menu, gpointer data) +{ + SPDesktopWidget *dtw = static_cast<SPDesktopWidget*>(data); + + GList* children = gtk_container_get_children (GTK_CONTAINER (menu)); + for ( auto iter = children ; iter ; iter = g_list_next (iter)) { + gtk_container_remove (GTK_CONTAINER (menu), GTK_WIDGET (iter->data)); + } + g_list_free (children); + + GtkWidget *item; + + item = gtk_menu_item_new_with_label ("-135°"); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_135), dtw); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("-90°"); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_90), dtw); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("-45°"); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_45), dtw); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("0°"); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_0), dtw); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("45°"); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_45), dtw); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("90°"); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_90), dtw); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("135°"); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_135), dtw); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("180°"); + g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_180), dtw); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + gtk_widget_show_all (GTK_WIDGET (menu)); +} + + +void +sp_desktop_widget_update_rotation (SPDesktopWidget *dtw) +{ + GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(dtw->rotation_status)); + + g_signal_handler_block(G_OBJECT(dtw->rotation_status), dtw->rotation_update); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (dtw->rotation_status), dtw->desktop->current_rotation() / M_PI * 180.0); + gtk_widget_queue_draw(GTK_WIDGET(dtw->rotation_status)); + if (window) + gdk_window_process_updates(window, TRUE); + g_signal_handler_unblock(G_OBJECT(dtw->rotation_status), dtw->rotation_update); } + +// --------------- Rulers/Scrollbars/Etc. ----------------- void sp_desktop_widget_toggle_rulers (SPDesktopWidget *dtw) { @@ -2211,7 +2271,6 @@ set_adjustment (GtkAdjustment *adj, double l, double u, double ps, double si, do gtk_adjustment_set_page_size(adj, ps); gtk_adjustment_set_step_increment(adj, si); gtk_adjustment_set_page_increment(adj, pi); - gtk_adjustment_changed (adj); } } diff --git a/src/widgets/desktop-widget.h b/src/widgets/desktop-widget.h index 08966ad5f..0d5f40987 100644 --- a/src/widgets/desktop-widget.h +++ b/src/widgets/desktop-widget.h @@ -40,6 +40,7 @@ void sp_desktop_widget_iconify(SPDesktopWidget *dtw); void sp_desktop_widget_maximize(SPDesktopWidget *dtw); void sp_desktop_widget_fullscreen(SPDesktopWidget *dtw); void sp_desktop_widget_update_zoom(SPDesktopWidget *dtw); +void sp_desktop_widget_update_rotation(SPDesktopWidget *dtw); void sp_desktop_widget_update_rulers (SPDesktopWidget *dtw); void sp_desktop_widget_update_hruler (SPDesktopWidget *dtw); void sp_desktop_widget_update_vruler (SPDesktopWidget *dtw); @@ -97,7 +98,9 @@ struct SPDesktopWidget { GtkWidget *select_status; GtkWidget *select_status_eventbox; GtkWidget *zoom_status; + GtkWidget *rotation_status; gulong zoom_update; + gulong rotation_update; Inkscape::UI::Widget::Dock *dock; @@ -191,6 +194,8 @@ struct SPDesktopWidget { { sp_desktop_widget_update_zoom (_dtw); } virtual void letZoomGrabFocus() { _dtw->letZoomGrabFocus(); } + virtual void updateRotation() + { sp_desktop_widget_update_rotation (_dtw); } virtual void setToolboxFocusTo (const gchar * id) { _dtw->setToolboxFocusTo (id); } virtual void setToolboxAdjustmentValue (const gchar *id, double val) diff --git a/src/widgets/dropper-toolbar.cpp b/src/widgets/dropper-toolbar.cpp index 45ed9ead4..4e26a99a0 100644 --- a/src/widgets/dropper-toolbar.cpp +++ b/src/widgets/dropper-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <glibmm/i18n.h> @@ -33,7 +33,7 @@ #include "dropper-toolbar.h" #include "document-undo.h" #include "widgets/ege-output-action.h" -#include "widgets/ink-action.h" +#include "ink-toggle-action.h" #include "preferences.h" #include "widgets/spinbutton-events.h" diff --git a/src/widgets/eek-preview.cpp b/src/widgets/eek-preview.cpp index 9951a8957..38d5173fa 100644 --- a/src/widgets/eek-preview.cpp +++ b/src/widgets/eek-preview.cpp @@ -61,11 +61,11 @@ typedef struct { int scaledW; int scaledH; - + int r; int g; int b; - + gboolean hot; gboolean within; gboolean takesFocus; @@ -194,7 +194,6 @@ static void eek_preview_size_request( GtkWidget* widget, GtkRequisition* req ) req->height = height; } -#if GTK_CHECK_VERSION(3,0,0) static void eek_preview_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width) { GtkRequisition requisition; @@ -208,7 +207,6 @@ static void eek_preview_get_preferred_height(GtkWidget *widget, gint *minimal_he eek_preview_size_request(widget, &requisition); *minimal_height = *natural_height = requisition.height; } -#endif enum { CLICKED_SIGNAL, @@ -219,22 +217,6 @@ enum { static guint eek_preview_signals[LAST_SIGNAL] = { 0 }; -#if !GTK_CHECK_VERSION(3,0,0) -static gboolean eek_preview_expose_event( GtkWidget* widget, GdkEventExpose* /* event */ ) -{ - gboolean result = FALSE; - - if (gtk_widget_is_drawable(widget)) { - GdkWindow* window = gtk_widget_get_window(widget); - cairo_t* cr = gdk_cairo_create(window); - result = eek_preview_draw(widget, cr); - cairo_destroy(cr); - } - - return result; -} -#endif - static gboolean eek_preview_draw(GtkWidget *widget, cairo_t *cr) @@ -245,14 +227,6 @@ gboolean eek_preview_draw(GtkWidget *widget, GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); - -#if !GTK_CHECK_VERSION(3,0,0) - GdkColor fg = { 0, - static_cast<guint16>(priv->r), - static_cast<guint16>(priv->g), - static_cast<guint16>(priv->b) - }; -#endif gint insetTop = 0, insetBottom = 0; gint insetLeft = 0, insetRight = 0; @@ -270,35 +244,17 @@ gboolean eek_preview_draw(GtkWidget *widget, insetLeft = insetRight = 1; } + auto context = gtk_widget_get_style_context(widget); -#if GTK_CHECK_VERSION(3,0,0) - GtkStyleContext *context = gtk_widget_get_style_context(widget); - gtk_render_frame(context, cr, 0, 0, allocation.width, allocation.height); - + gtk_render_background(context, cr, 0, 0, allocation.width, allocation.height); -#else - GtkStyle *style = gtk_widget_get_style(widget); - GdkWindow *window = gtk_widget_get_window(widget); - - gtk_paint_flat_box( style, - window, - (GtkStateType)gtk_widget_get_state(widget), - GTK_SHADOW_NONE, - NULL, - widget, - NULL, - 0, 0, - allocation.width, allocation.height); - - gdk_colormap_alloc_color( gdk_colormap_get_system(), &fg, FALSE, TRUE ); -#endif // Border if (priv->border != BORDER_NONE) { @@ -313,26 +269,19 @@ gboolean eek_preview_draw(GtkWidget *widget, if (priv->previewPixbuf ) { - GtkDrawingArea *da = &(preview->drawing); - GdkWindow *da_window = gtk_widget_get_window(GTK_WIDGET(da)); - cairo_t *cr = gdk_cairo_create(da_window); - - gint w = gdk_window_get_width(da_window); - gint h = gdk_window_get_height(da_window); - - if ((w != priv->scaledW) || (h != priv->scaledH)) { + if ((allocation.width != priv->scaledW) || (allocation.height != priv->scaledH)) { if (priv->scaled) { g_object_unref(priv->scaled); } + priv->scaledW = allocation.width - (insetLeft + insetRight); + priv->scaledH = allocation.height - (insetTop + insetBottom); + priv->scaled = gdk_pixbuf_scale_simple(priv->previewPixbuf, - w - (insetLeft + insetRight), - h - (insetTop + insetBottom), + priv->scaledW, + priv->scaledH, GDK_INTERP_BILINEAR); - - priv->scaledW = w - (insetLeft + insetRight); - priv->scaledH = h - (insetTop + insetBottom); } GdkPixbuf *pix = (priv->scaled) ? priv->scaled : priv->previewPixbuf; @@ -346,7 +295,6 @@ gboolean eek_preview_draw(GtkWidget *widget, gdk_cairo_set_source_pixbuf(cr, pix, insetLeft, insetTop); cairo_paint(cr); - cairo_destroy(cr); } if (priv->linked) @@ -377,27 +325,12 @@ gboolean eek_preview_draw(GtkWidget *widget, if (priv->linked & PREVIEW_LINK_IN) { -#if GTK_CHECK_VERSION(3,0,0) gtk_render_arrow(context, cr, G_PI, // Down-pointing arrow area.x, area.y, min(area.width, area.height) ); -#else - gtk_paint_arrow( style, - window, - gtk_widget_get_state (widget), - GTK_SHADOW_ETCHED_IN, - NULL, /* clip area. &area, */ - widget, /* may be NULL */ - NULL, /* detail */ - GTK_ARROW_DOWN, - FALSE, - area.x, area.y, - area.width, area.height - ); -#endif } if (priv->linked & PREVIEW_LINK_OUT) @@ -407,27 +340,12 @@ gboolean eek_preview_draw(GtkWidget *widget, otherArea.y = possible.y + (possible.height - otherArea.height); } -#if GTK_CHECK_VERSION(3,0,0) gtk_render_arrow(context, cr, G_PI, // Down-pointing arrow otherArea.x, otherArea.y, min(otherArea.width, otherArea.height) ); -#else - gtk_paint_arrow( style, - window, - gtk_widget_get_state (widget), - GTK_SHADOW_ETCHED_OUT, - NULL, /* clip area. &area, */ - widget, /* may be NULL */ - NULL, /* detail */ - GTK_ARROW_DOWN, - FALSE, - otherArea.x, otherArea.y, - otherArea.width, otherArea.height - ); -#endif } if (priv->linked & PREVIEW_LINK_OTHER) @@ -437,27 +355,12 @@ gboolean eek_preview_draw(GtkWidget *widget, otherArea.y = possible.y + (possible.height - otherArea.height) / 2; } -#if GTK_CHECK_VERSION(3,0,0) gtk_render_arrow(context, cr, 1.5*G_PI, // Left-pointing arrow otherArea.x, otherArea.y, min(otherArea.width, otherArea.height) ); -#else - gtk_paint_arrow( style, - window, - gtk_widget_get_state (widget), - GTK_SHADOW_ETCHED_OUT, - NULL, /* clip area. &area, */ - widget, /* may be NULL */ - NULL, /* detail */ - GTK_ARROW_LEFT, - FALSE, - otherArea.x, otherArea.y, - otherArea.width, otherArea.height - ); -#endif } @@ -469,22 +372,10 @@ gboolean eek_preview_draw(GtkWidget *widget, if ( otherArea.height < possible.height ) { otherArea.y = possible.y + (possible.height - otherArea.height) / 2; } -#if GTK_CHECK_VERSION(3,0,0) gtk_render_check(context, cr, otherArea.x, otherArea.y, otherArea.width, otherArea.height ); -#else - gtk_paint_check( style, - window, - gtk_widget_get_state (widget), - GTK_SHADOW_ETCHED_OUT, - NULL, - widget, - NULL, - otherArea.x, otherArea.y, - otherArea.width, otherArea.height ); -#endif } if (priv->linked & PREVIEW_STROKE) @@ -495,23 +386,11 @@ gboolean eek_preview_draw(GtkWidget *widget, if ( otherArea.height < possible.height ) { otherArea.y = possible.y + (possible.height - otherArea.height) / 2; } -#if GTK_CHECK_VERSION(3,0,0) // This should be a diamond too? gtk_render_check(context, cr, otherArea.x, otherArea.y, otherArea.width, otherArea.height ); -#else - gtk_paint_diamond( style, - window, - gtk_widget_get_state (widget), - GTK_SHADOW_ETCHED_OUT, - NULL, - widget, - NULL, - otherArea.x, otherArea.y, - otherArea.width, otherArea.height ); -#endif } } @@ -519,21 +398,10 @@ gboolean eek_preview_draw(GtkWidget *widget, if ( gtk_widget_has_focus(widget) ) { gtk_widget_get_allocation (widget, &allocation); -#if GTK_CHECK_VERSION(3,0,0) gtk_render_focus(context, cr, 0 + 1, 0 + 1, allocation.width - 2, allocation.height - 2 ); -#else - gtk_paint_focus( style, - window, - GTK_STATE_NORMAL, - NULL, /* GdkRectangle *area, */ - widget, - NULL, - 0 + 1, 0 + 1, - allocation.width - 2, allocation.height - 2 ); -#endif } return FALSE; @@ -547,11 +415,7 @@ static gboolean eek_preview_enter_cb( GtkWidget* widget, GdkEventCrossing* event EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); priv->within = TRUE; -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_state_flags( widget, priv->hot ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_PRELIGHT, false ); -#else - gtk_widget_set_state( widget, priv->hot ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT ); -#endif } return FALSE; @@ -564,11 +428,7 @@ static gboolean eek_preview_leave_cb( GtkWidget* widget, GdkEventCrossing* event EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); priv->within = FALSE; -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_state_flags( widget, GTK_STATE_FLAG_NORMAL, false ); -#else - gtk_widget_set_state( widget, GTK_STATE_NORMAL ); -#endif } return FALSE; @@ -593,11 +453,7 @@ static gboolean eek_preview_button_press_cb( GtkWidget* widget, GdkEventButton* if ( priv->within ) { -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_state_flags( widget, GTK_STATE_FLAG_ACTIVE, false ); -#else - gtk_widget_set_state( widget, GTK_STATE_ACTIVE ); -#endif } } } @@ -612,14 +468,10 @@ static gboolean eek_preview_button_release_cb( GtkWidget* widget, GdkEventButton EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); priv->hot = FALSE; -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_state_flags( widget, GTK_STATE_FLAG_NORMAL, false ); -#else - gtk_widget_set_state( widget, GTK_STATE_NORMAL ); -#endif if ( priv->within && - (event->button == PRIME_BUTTON_MAGIC_NUMBER || + (event->button == PRIME_BUTTON_MAGIC_NUMBER || event->button == 2)) { gboolean isAlt = ( ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) || @@ -697,15 +549,9 @@ static void eek_preview_class_init( EekPreviewClass *klass ) parent_class = (GtkWidgetClass*)g_type_class_peek_parent( klass ); -#if GTK_CHECK_VERSION(3,0,0) widgetClass->get_preferred_width = eek_preview_get_preferred_width; widgetClass->get_preferred_height = eek_preview_get_preferred_height; widgetClass->draw = eek_preview_draw; -#else - widgetClass->size_request = eek_preview_size_request; - widgetClass->expose_event = eek_preview_expose_event; -#endif - widgetClass->button_press_event = eek_preview_button_press_cb; widgetClass->button_release_event = eek_preview_button_release_cb; widgetClass->enter_notify_event = eek_preview_enter_cb; @@ -753,7 +599,7 @@ eek_preview_set_linked(EekPreview *preview, EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); g_return_if_fail(IS_EEK_PREVIEW(preview)); - + link = (LinkType)(link & PREVIEW_LINK_ALL); if (link != (LinkType)priv->linked) @@ -802,7 +648,7 @@ eek_preview_set_details(EekPreview *preview, guint border) { EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); - + g_return_if_fail(IS_EEK_PREVIEW(preview)); priv->view = view; diff --git a/src/widgets/ege-adjustment-action.cpp b/src/widgets/ege-adjustment-action.cpp index 272217aa4..6678d1e5a 100644 --- a/src/widgets/ege-adjustment-action.cpp +++ b/src/widgets/ege-adjustment-action.cpp @@ -47,7 +47,7 @@ #include "icon-size.h" #include "widgets/ege-adjustment-action.h" -#include "ui/widget/gimpspinscale.h" +#include "gimp/gimpspinscale.h" #include "ui/icon-names.h" @@ -813,12 +813,8 @@ static GtkWidget* create_tool_item( GtkAction* action ) if ( IS_EGE_ADJUSTMENT_ACTION(action) ) { EgeAdjustmentAction* act = EGE_ADJUSTMENT_ACTION( action ); GtkWidget* spinbutton = 0; -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget* hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); + auto hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); -#else - GtkWidget* hb = gtk_hbox_new( FALSE, 5 ); -#endif GValue value; memset( &value, 0, sizeof(value) ); g_value_init( &value, G_TYPE_STRING ); @@ -865,13 +861,7 @@ static GtkWidget* create_tool_item( GtkAction* action ) gtk_box_pack_start( GTK_BOX(hb), icon, FALSE, FALSE, 0 ); } else { GtkWidget* lbl = gtk_label_new( g_value_get_string( &value ) ? g_value_get_string( &value ) : "wwww" ); - -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_halign(lbl, GTK_ALIGN_END); -#else - gtk_misc_set_alignment( GTK_MISC(lbl), 1.0, 0.5 ); -#endif - gtk_box_pack_start( GTK_BOX(hb), lbl, FALSE, FALSE, 0 ); } } diff --git a/src/widgets/ege-output-action.cpp b/src/widgets/ege-output-action.cpp index 5dece8e91..da29524a5 100644 --- a/src/widgets/ege-output-action.cpp +++ b/src/widgets/ege-output-action.cpp @@ -166,12 +166,8 @@ GtkWidget* create_tool_item( GtkAction* action ) if ( IS_EGE_OUTPUT_ACTION(action) ) { GValue value; -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget* hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); + auto hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); -#else - GtkWidget* hb = gtk_hbox_new( FALSE, 5 ); -#endif GtkWidget* lbl = 0; memset( &value, 0, sizeof(value) ); diff --git a/src/widgets/ege-select-one-action.cpp b/src/widgets/ege-select-one-action.cpp index 2e106154e..5555663e4 100644 --- a/src/widgets/ege-select-one-action.cpp +++ b/src/widgets/ege-select-one-action.cpp @@ -632,12 +632,8 @@ GtkWidget* create_tool_item( GtkAction* action ) item = GTK_WIDGET( gtk_tool_item_new() ); if ( act->private_data->appearanceMode == APPEARANCE_FULL ) { -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget* holder = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + auto holder = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(holder), FALSE); -#else - GtkWidget* holder = gtk_hbox_new( FALSE, 0 ); -#endif GtkRadioAction* ract = 0; GSList* group = 0; @@ -744,12 +740,8 @@ GtkWidget* create_tool_item( GtkAction* action ) gtk_container_add( GTK_CONTAINER(item), holder ); } else { -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget* holder = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); + auto holder = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); gtk_box_set_homogeneous(GTK_BOX(holder), FALSE); -#else - GtkWidget *holder = gtk_hbox_new( FALSE, 4 ); -#endif GtkEntry *entry = 0; GtkWidget *normal; @@ -818,14 +810,8 @@ GtkWidget* create_tool_item( GtkAction* action ) gtk_box_pack_start( GTK_BOX(holder), normal, FALSE, FALSE, 0 ); { -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_halign(holder, GTK_ALIGN_START); gtk_container_add(GTK_CONTAINER(item), holder); -#else - GtkWidget *align = gtk_alignment_new(0, 0.5, 0, 0); - gtk_container_add( GTK_CONTAINER(align), holder); - gtk_container_add( GTK_CONTAINER(item), align ); -#endif } } @@ -861,13 +847,6 @@ void resync_active( EgeSelectOneAction* act, gint active, gboolean override ) if ( children && children->data ) { gpointer combodata = g_object_get_data( G_OBJECT(children->data), "ege-combo-box" ); -#if !GTK_CHECK_VERSION(3,0,0) - if (!combodata && GTK_IS_ALIGNMENT(children->data)) { - GList *other = gtk_container_get_children( GTK_CONTAINER(children->data) ); - combodata = g_object_get_data( G_OBJECT(other->data), "ege-combo-box" ); - } -#endif - if ( GTK_IS_COMBO_BOX(combodata) ) { GtkComboBox* combo = GTK_COMBO_BOX(combodata); if ((active == -1) && (gtk_combo_box_get_has_entry(combo))) { @@ -925,13 +904,6 @@ void resync_sensitive( EgeSelectOneAction* act ) if ( children && children->data ) { gpointer combodata = g_object_get_data( G_OBJECT(children->data), "ege-combo-box" ); -#if !GTK_CHECK_VERSION(3,0,0) - if (!combodata && GTK_IS_ALIGNMENT(children->data)) { - GList *other = gtk_container_get_children( GTK_CONTAINER(children->data) ); - combodata = g_object_get_data( G_OBJECT(other->data), "ege-combo-box" ); - } -#endif - if ( GTK_IS_COMBO_BOX(combodata) ) { /* Not implemented */ } else if ( GTK_IS_BOX(children->data) ) { diff --git a/src/widgets/eraser-toolbar.cpp b/src/widgets/eraser-toolbar.cpp index bb553f4e6..7377cdc00 100644 --- a/src/widgets/eraser-toolbar.cpp +++ b/src/widgets/eraser-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <glibmm/i18n.h> @@ -33,14 +33,18 @@ #include "eraser-toolbar.h" #include "calligraphy-toolbar.h" // TODO: needed for update_presets_list +#include <array> + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" #include "widgets/ege-select-one-action.h" -#include "widgets/ink-action.h" -#include "preferences.h" +#include "ink-action.h" +#include "ink-radio-action.h" +#include "ink-toggle-action.h" #include "toolbox.h" #include "ui/icon-names.h" +#include "ui/tools/eraser-tool.h" using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; @@ -64,33 +68,54 @@ static void sp_erc_mass_value_changed( GtkAdjustment *adj, GObject* tbl ) update_presets_list(tbl); } +static void sp_erc_velthin_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/tools/eraser/thinning", gtk_adjustment_get_value(adj) ); + update_presets_list(tbl); +} + +static void sp_erc_cap_rounding_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/eraser/cap_rounding", gtk_adjustment_get_value(adj) ); + update_presets_list(tbl); +} + +static void sp_erc_tremor_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/eraser/tremor", gtk_adjustment_get_value(adj) ); + update_presets_list(tbl); +} + +static void sp_set_tbl_eraser_mode_visibility(GObject *const tbl, const guint eraser_mode) +{ + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "split") ), (eraser_mode == ERASER_MODE_CUT)); + + const gboolean visibility = (eraser_mode != ERASER_MODE_DELETE); + const std::array<const gchar *, 6> arr = {"cap_rounding", "mass", "thinning", "tremor", "usepressure", "width"}; + for (const gchar * str : arr) { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, str) ), visibility ); + } +} + static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - bool eraserMode = ege_select_one_action_get_active( act ) != 0; + guint eraser_mode = ege_select_one_action_get_active( act ); if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool( "/tools/eraser/mode", eraserMode ); - } - GtkAction *split = GTK_ACTION( g_object_get_data(tbl, "split") ); - GtkAction *mass = GTK_ACTION( g_object_get_data(tbl, "mass") ); - GtkAction *width = GTK_ACTION( g_object_get_data(tbl, "width") ); - if(eraserMode == TRUE){ - gtk_action_set_visible( split, TRUE ); - gtk_action_set_visible( mass, TRUE ); - gtk_action_set_visible( width, TRUE ); - } else { - gtk_action_set_visible( split, FALSE ); - gtk_action_set_visible( mass, FALSE ); - gtk_action_set_visible( width, FALSE ); + prefs->setInt( "/tools/eraser/mode", eraser_mode ); } + sp_set_tbl_eraser_mode_visibility(tbl, eraser_mode); // only take action if run by the attr_changed listener if (!g_object_get_data( tbl, "freeze" )) { // in turn, prevent listener from responding g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); /* - if ( eraserMode != 0 ) { + if ( eraser_mode != ERASER_MODE_DELETE ) { } else { } */ @@ -111,7 +136,7 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb { Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint eraserMode = FALSE; + gint eraser_mode = FALSE; { GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); GtkTreeIter iter; @@ -125,10 +150,17 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, 0, _("Cut"), - 1, _("Cut out from objects"), + 1, _("Cut out from paths and shapes"), 2, INKSCAPE_ICON("path-difference"), -1 ); + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, + 0, _("Clip"), + 1, _("Clip from objects"), + 2, INKSCAPE_ICON("path-intersection"), + -1 ); + EgeSelectOneAction* act = ege_select_one_action_new( "EraserModeAction", (""), (""), NULL, GTK_TREE_MODEL(model) ); g_object_set( act, "short_label", _("Mode:"), NULL ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); @@ -137,12 +169,13 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb ege_select_one_action_set_appearance( act, "full" ); ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); - ege_select_one_action_set_icon_column( act, 2 ); - ege_select_one_action_set_tooltip_column( act, 1 ); + 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); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - eraserMode = prefs->getBool("/tools/eraser/mode") ? TRUE : FALSE; - ege_select_one_action_set_active( act, eraserMode ); + eraser_mode = prefs->getInt("/tools/eraser/mode", ERASER_MODE_CLIP); + ege_select_one_action_set_active( act, eraser_mode ); g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_erasertb_mode_changed), holder ); } @@ -163,6 +196,71 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb g_object_set_data( holder, "width", eact ); gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); } + /* Use Pressure button */ + { + InkToggleAction* act = ink_toggle_action_new( "EraserPressureAction", + _("Eraser Pressure"), + _("Use the pressure of the input device to alter the width of the pen"), + INKSCAPE_ICON("draw-use-pressure"), + Inkscape::ICON_SIZE_DECORATION ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/eraser/usepressure", update_presets_list, holder); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + g_object_set_data( holder, "usepressure", act ); + } + { + + /* Thinning */ + gchar const* labels[] = {_("(speed blows up stroke)"), 0, 0, _("(slight widening)"), _("(constant width)"), _("(slight thinning, default)"), 0, 0, _("(speed deflates stroke)")}; + gdouble values[] = {-100, -40, -20, -10, 0, 10, 20, 40, 100}; + EgeAdjustmentAction* eact = create_adjustment_action( "EraserThinningAction", + _("Eraser Stroke Thinning"), _("Thinning:"), + _("How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 makes them broader, 0 makes width independent of velocity)"), + "/tools/eraser/thinning", 10, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + -100, 100, 1, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_erc_velthin_value_changed, NULL /*unit tracker*/, 1, 0); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + g_object_set_data( holder, "thinning", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + { + /* Cap Rounding */ + gchar const* labels[] = {_("(blunt caps, default)"), _("(slightly bulging)"), 0, 0, _("(approximately round)"), _("(long protruding caps)")}; + gdouble values[] = {0, 0.3, 0.5, 1.0, 1.4, 5.0}; + // TRANSLATORS: "cap" means "end" (both start and finish) here + EgeAdjustmentAction* eact = create_adjustment_action( "EraserCapRoundingAction", + _("Eraser Cap rounding"), _("Caps:"), + _("Increase to make caps at the ends of strokes protrude more (0 = no caps, 1 = round caps)"), + "/tools/eraser/cap_rounding", 0.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 5.0, 0.01, 0.1, + labels, values, G_N_ELEMENTS(labels), + sp_erc_cap_rounding_value_changed, NULL /*unit tracker*/, 0.01, 2 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + g_object_set_data( holder, "cap_rounding", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + { + /* Tremor */ + gchar const* labels[] = {_("(smooth line)"), _("(slight tremor)"), _("(noticeable tremor)"), 0, 0, _("(maximum tremor)")}; + gdouble values[] = {0, 10, 20, 40, 60, 100}; + EgeAdjustmentAction* eact = create_adjustment_action( "EraserTremorAction", + _("EraserStroke Tremor"), _("Tremor:"), + _("Increase to make strokes rugged and trembling"), + "/tools/eraser/tremor", 0.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 100, 1, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_erc_tremor_value_changed, NULL /*unit tracker*/, 1, 0); + + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + g_object_set_data( holder, "tremor", eact ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } { /* Mass */ gchar const* labels[] = {_("(no inertia)"), _("(slight smoothing, default)"), _("(noticeable lagging)"), 0, 0, _("(maximum inertia)")}; @@ -192,19 +290,7 @@ void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toogle_break_apart), holder) ; gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); } - GtkAction *split = GTK_ACTION( g_object_get_data(holder, "split") ); - GtkAction *mass = GTK_ACTION( g_object_get_data(holder, "mass") ); - GtkAction *width = GTK_ACTION( g_object_get_data(holder, "width") ); - if(eraserMode == TRUE){ - gtk_action_set_visible( split, TRUE ); - gtk_action_set_visible( mass, TRUE ); - gtk_action_set_visible( width, TRUE ); - } else { - gtk_action_set_visible( split, FALSE ); - gtk_action_set_visible( mass, FALSE ); - gtk_action_set_visible( width, FALSE ); - } - + sp_set_tbl_eraser_mode_visibility(holder, eraser_mode); } /* diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp index a96776894..8946eb4b3 100644 --- a/src/widgets/fill-style.cpp +++ b/src/widgets/fill-style.cpp @@ -19,7 +19,7 @@ #define noSP_FS_VERBOSE #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <gtkmm/box.h> @@ -27,8 +27,6 @@ #include "verbs.h" -#include <gtk/gtk.h> - #include "desktop.h" #include "selection.h" @@ -38,13 +36,13 @@ #include "document-undo.h" #include "gradient-chemistry.h" #include "inkscape.h" -#include "selection.h" #include "sp-linear-gradient.h" +#include "sp-mesh-gradient.h" #include "sp-pattern.h" #include "sp-radial-gradient.h" +#include "sp-text.h" #include "style.h" #include "widgets/paint-selector.h" -#include "xml/repr.h" #include "fill-style.h" #include "fill-n-stroke-factory.h" @@ -282,26 +280,35 @@ void FillNStroke::performUpdate() SPPaintServer *server = (kind == FILL) ? query.getFillPaintServer() : query.getStrokePaintServer(); - if (server && SP_IS_GRADIENT(server) && SP_GRADIENT(server)->getVector()->isSwatch()) { - SPGradient *vector = SP_GRADIENT(server)->getVector(); - psel->setSwatch( vector ); - } else if (SP_IS_LINEARGRADIENT(server)) { - SPGradient *vector = SP_GRADIENT(server)->getVector(); - psel->setGradientLinear( vector ); - - SPLinearGradient *lg = SP_LINEARGRADIENT(server); - 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( rg->getUnits(), - rg->getSpread() ); - } else if (SP_IS_PATTERN(server)) { - SPPattern *pat = SP_PATTERN(server)->rootPattern(); - psel->updatePatternList( pat ); + if (server) { + if (SP_IS_GRADIENT(server) && SP_GRADIENT(server)->getVector()->isSwatch()) { + SPGradient *vector = SP_GRADIENT(server)->getVector(); + psel->setSwatch( vector ); + } else if (SP_IS_LINEARGRADIENT(server)) { + SPGradient *vector = SP_GRADIENT(server)->getVector(); + psel->setGradientLinear( vector ); + + SPLinearGradient *lg = SP_LINEARGRADIENT(server); + 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( rg->getUnits(), + rg->getSpread() ); +#ifdef WITH_MESH + } else if (SP_IS_MESHGRADIENT(server)) { + SPGradient *array = SP_GRADIENT(server)->getArray(); + psel->setGradientMesh( SP_MESHGRADIENT(array) ); + SPMeshGradient *mg = SP_MESHGRADIENT(server); + psel->updateMeshList( SP_MESHGRADIENT( array )); +#endif + } else if (SP_IS_PATTERN(server)) { + SPPattern *pat = SP_PATTERN(server)->rootPattern(); + psel->updatePatternList( pat ); + } } } break; @@ -476,7 +483,7 @@ void FillNStroke::updateFromPaint() SPDocument *document = desktop->getDocument(); Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> const items = selection->itemList(); + std::vector<SPItem*> const items(selection->items().begin(), selection->items().end()); switch (psel->mode) { case SPPaintSelector::MODE_EMPTY: @@ -617,6 +624,107 @@ void FillNStroke::updateFromPaint() } break; +#ifdef WITH_MESH + case SPPaintSelector::MODE_GRADIENT_MESH: + + if (!items.empty()) { + SPGradientType const gradient_type = SP_GRADIENT_TYPE_MESH; + + SPCSSAttr *css = 0; + if (kind == FILL) { + // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs + css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, "fill-opacity", "1.0"); + } + + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + SPDefs *defs = document->getDefs(); + + SPMeshGradient * mesh = psel->getMeshGradient(); + + for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end(); ++i){ + + //FIXME: see above + if (kind == FILL) { + sp_repr_css_change_recursive((*i)->getRepr(), css, "style"); + } + + // Check if object already has mesh. + bool has_mesh = false; + SPStyle *style = (*i)->style; + if (style) { + SPPaintServer *server = + (kind==FILL) ? style->getFillPaintServer():style->getStrokePaintServer(); + if (server && SP_IS_MESHGRADIENT(server)) + has_mesh = true; + } + + if (!mesh || !has_mesh) { + // No mesh in document or object does not already have mesh -> + // Create new mesh. + + // Create mesh element + Inkscape::XML::Node *repr = xml_doc->createElement("svg:meshgradient"); + + // privates are garbage-collectable + repr->setAttribute("inkscape:collect", "always"); + + // Attach to document + defs->getRepr()->appendChild(repr); + Inkscape::GC::release(repr); + + // Get corresponding object + SPMeshGradient *mg = static_cast<SPMeshGradient *>(document->getObjectByRepr(repr)); + mg->array.create(mg, *i, (kind==FILL) ? + (*i)->geometricBounds() : (*i)->visualBounds()); + + bool isText = SP_IS_TEXT(*i); + sp_style_set_property_url (*i, ((kind == FILL) ? "fill":"stroke"), + mg, isText); + + // (*i)->requestModified(SP_OBJECT_MODIFIED_FLAG|SP_OBJECT_STYLE_MODIFIED_FLAG); + + } else { + // Using found mesh + + // Duplicate + Inkscape::XML::Node *mesh_repr = mesh->getRepr(); + Inkscape::XML::Node *copy_repr = mesh_repr->duplicate(xml_doc); + + // privates are garbage-collectable + copy_repr->setAttribute("inkscape:collect", "always"); + + // Attach to document + defs->getRepr()->appendChild(copy_repr); + Inkscape::GC::release(copy_repr); + + // Get corresponding object + SPMeshGradient *mg = + static_cast<SPMeshGradient *>(document->getObjectByRepr(copy_repr)); + // std::cout << " " << (mg->getId()?mg->getId():"null") << std::endl; + mg->array.read(mg); + + Geom::OptRect item_bbox = (kind==FILL) ? + (*i)->geometricBounds() : (*i)->visualBounds(); + mg->array.fill_box( item_bbox ); + + bool isText = SP_IS_TEXT(*i); + sp_style_set_property_url (*i, ((kind == FILL) ? "fill":"stroke"), + mg, isText); + } + } + + if (css) { + sp_repr_css_attr_unref(css); + css = 0; + } + + DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, + (kind == FILL) ? _("Set mesh on fill") : _("Set mesh on stroke")); + } + break; +#endif + case SPPaintSelector::MODE_PATTERN: if (!items.empty()) { diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index aefcb2e81..819ac77b6 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -16,31 +16,22 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <libnrtype/font-lister.h> #include <libnrtype/font-instance.h> -#include <2geom/transforms.h> - -#include <gtk/gtk.h> - #include <glibmm/i18n.h> #include "desktop.h" #include "widgets/font-selector.h" -#include "preferences.h" /* SPFontSelector */ struct SPFontSelector { -#if GTK_CHECK_VERSION(3,0,0) GtkBox hbox; -#else - GtkHBox hbox; -#endif unsigned int block_emit : 1; @@ -61,11 +52,7 @@ struct SPFontSelector struct SPFontSelectorClass { -#if GTK_CHECK_VERSION(3,0,0) GtkBoxClass parent_class; -#else - GtkHBoxClass parent_class; -#endif void (* font_set) (SPFontSelector *fsel, gchar *fontspec); }; @@ -91,11 +78,7 @@ static void sp_font_selector_set_sizes( SPFontSelector *fsel ); static guint fs_signals[LAST_SIGNAL] = { 0 }; -#if GTK_CHECK_VERSION(3,0,0) G_DEFINE_TYPE(SPFontSelector, sp_font_selector, GTK_TYPE_BOX); -#else -G_DEFINE_TYPE(SPFontSelector, sp_font_selector, GTK_TYPE_HBOX); -#endif static void sp_font_selector_class_init(SPFontSelectorClass *c) { @@ -127,8 +110,8 @@ static void sp_font_selector_set_size_tooltip(SPFontSelector *fsel) */ static void sp_font_selector_init(SPFontSelector *fsel) { - gtk_box_set_homogeneous(GTK_BOX(fsel), TRUE); - gtk_box_set_spacing(GTK_BOX(fsel), 4); + //gtk_box_set_homogeneous(GTK_BOX(fsel), TRUE); + //gtk_box_set_spacing(GTK_BOX(fsel), 4); /* Family frame */ GtkWidget *f = gtk_frame_new(_("Font family")); @@ -150,6 +133,7 @@ static void sp_font_selector_init(SPFontSelector *fsel) GtkTreeViewColumn *column = gtk_tree_view_column_new (); GtkCellRenderer *cell = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, cell, FALSE); + gtk_tree_view_column_set_fixed_width (column, 200); gtk_tree_view_column_set_attributes (column, cell, "text", 0, NULL); gtk_tree_view_column_set_cell_data_func (column, cell, GtkTreeCellDataFunc (font_lister_cell_data_func), @@ -160,23 +144,11 @@ static void sp_font_selector_init(SPFontSelector *fsel) /* Muck with style, see text-toolbar.cpp */ gtk_widget_set_name( GTK_WIDGET(fsel->family_treeview), "font_selector_family" ); -#if GTK_CHECK_VERSION(3,0,0) - GtkCssProvider *css_provider = gtk_css_provider_new(); - gtk_css_provider_load_from_data(css_provider, - "#font_selector_family {\n" - " -GtkWidget-wide-separators: true;\n" - " -GtkWidget-separator-height: 6;\n" - "}\n", - -1, NULL); - - GdkScreen *screen = gdk_screen_get_default(); + auto css_provider = gtk_css_provider_new(); + auto screen = gdk_screen_get_default(); gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER); -#else - gtk_rc_parse_string ( - "widget \"*font_selector_family\" style \"fontfamily-separator-style\""); -#endif Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); Glib::RefPtr<Gtk::ListStore> store = fontlister->get_font_list(); @@ -193,14 +165,10 @@ static void sp_font_selector_init(SPFontSelector *fsel) /* Style frame */ f = gtk_frame_new(C_("Font selector", "Style")); gtk_widget_show(f); - gtk_box_pack_start(GTK_BOX (fsel), f, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX (fsel), f, FALSE, TRUE, 0); -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); + auto vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); gtk_box_set_homogeneous(GTK_BOX(vb), FALSE); -#else - GtkWidget *vb = gtk_vbox_new(FALSE, 4); -#endif gtk_widget_show(vb); gtk_container_set_border_width(GTK_CONTAINER (vb), 4); gtk_container_add(GTK_CONTAINER(f), vb); @@ -235,12 +203,8 @@ static void sp_font_selector_init(SPFontSelector *fsel) selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(fsel->style_treeview)); g_signal_connect (G_OBJECT(selection), "changed", G_CALLBACK (sp_font_selector_style_select_row), fsel); -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); + auto hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); -#else - GtkWidget *hb = gtk_hbox_new(FALSE, 4); -#endif gtk_widget_show(hb); gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, FALSE, 0); diff --git a/src/widgets/gimp/CMakeLists.txt b/src/widgets/gimp/CMakeLists.txt new file mode 100644 index 000000000..7b3e834e3 --- /dev/null +++ b/src/widgets/gimp/CMakeLists.txt @@ -0,0 +1,13 @@ +set(gimpwidgets_SRC + gimpcolorwheel.c + gimpspinscale.c + ruler.cpp + + # ------- + # Headers + gimpcolorwheel.h + gimpspinscale.h + ruler.h +) + +add_inkscape_source("${gimpwidgets_SRC}") diff --git a/src/widgets/gimp/gimpcolorwheel.c b/src/widgets/gimp/gimpcolorwheel.c new file mode 100644 index 000000000..212391497 --- /dev/null +++ b/src/widgets/gimp/gimpcolorwheel.c @@ -0,0 +1,1467 @@ +/* HSV color selector for GTK+ + * + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Simon Budig <Simon.Budig@unix-ag.org> (original code) + * Federico Mena-Quintero <federico@gimp.org> (cleanup for GTK+) + * Jonathan Blandford <jrb@redhat.com> (cleanup for GTK+) + * Michael Natterer <mitch@gimp.org> (ported back to GIMP) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * This widget was adopted by Inkscape by Alex Valavanis <valavanisalex@gmail.com> + * on 2013-01-08. Last merges with GIMP code were applied using the following + * commits from the GIMP git repository at + * http://git.gnome.org/browse/gimp/tree/modules/gimpcolorwheel.c + * + * Gtk+ 2 code merge: commit 632c5 (2013-01-06) + * Gtk+ 3 code merge: commit bcfc6, gtk3-port branch (2013-01-06) + */ + +#include "config.h" + +#include <gtk/gtk.h> +#include <gdk/gdkkeysyms.h> + +#include "gimpcolorwheel.h" +#include <math.h> + + +/* Default ring fraction */ +#define DEFAULT_FRACTION 0.1 + +/* Default width/height */ +#define DEFAULT_SIZE 100 + +/* Default ring width */ +#define DEFAULT_RING_WIDTH 10 + + +/* Dragging modes */ +typedef enum +{ + DRAG_NONE, + DRAG_H, + DRAG_SV +} DragMode; + +/* Private part of the GimpColorWheel structure */ +typedef struct +{ + /* Color value */ + gdouble h; + gdouble s; + gdouble v; + + /* ring_width is this fraction of size */ + gdouble ring_fraction; + + /* Size and ring width */ + gint size; + gint ring_width; + + /* Window for capturing events */ + GdkWindow *window; + + /* Dragging mode */ + DragMode mode; + + guint focus_on_ring : 1; +} GimpColorWheelPrivate; + +enum +{ + CHANGED, + MOVE, + LAST_SIGNAL +}; + +static void gimp_color_wheel_map (GtkWidget *widget); +static void gimp_color_wheel_unmap (GtkWidget *widget); +static void gimp_color_wheel_realize (GtkWidget *widget); +static void gimp_color_wheel_unrealize (GtkWidget *widget); +static void gimp_color_wheel_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static gboolean gimp_color_wheel_button_press (GtkWidget *widget, + GdkEventButton *event); +static gboolean gimp_color_wheel_button_release (GtkWidget *widget, + GdkEventButton *event); +static gboolean gimp_color_wheel_motion (GtkWidget *widget, + GdkEventMotion *event); +static gboolean gimp_color_wheel_draw (GtkWidget *widget, + cairo_t *cr); +static void gimp_color_wheel_get_preferred_width (GtkWidget *widget, + gint *minimum_width, + gint *natural_width); +static void gimp_color_wheel_get_preferred_height (GtkWidget *widget, + gint *minimum_height, + gint *natural_height); +static gboolean gimp_color_wheel_grab_broken (GtkWidget *widget, + GdkEventGrabBroken *event); +static gboolean gimp_color_wheel_focus (GtkWidget *widget, + GtkDirectionType direction); +static void gimp_color_wheel_move (GimpColorWheel *wheel, + GtkDirectionType dir); + + +static guint wheel_signals[LAST_SIGNAL]; + +G_DEFINE_TYPE (GimpColorWheel, gimp_color_wheel, GTK_TYPE_WIDGET) + +#define parent_class gimp_color_wheel_parent_class + + +static void +gimp_color_wheel_class_init (GimpColorWheelClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); + GimpColorWheelClass *wheel_class = GIMP_COLOR_WHEEL_CLASS (class); + GtkBindingSet *binding_set; + + widget_class->map = gimp_color_wheel_map; + widget_class->unmap = gimp_color_wheel_unmap; + widget_class->realize = gimp_color_wheel_realize; + widget_class->unrealize = gimp_color_wheel_unrealize; + widget_class->size_allocate = gimp_color_wheel_size_allocate; + widget_class->button_press_event = gimp_color_wheel_button_press; + widget_class->button_release_event = gimp_color_wheel_button_release; + widget_class->motion_notify_event = gimp_color_wheel_motion; + widget_class->get_preferred_width = gimp_color_wheel_get_preferred_width; + widget_class->get_preferred_height = gimp_color_wheel_get_preferred_height; + widget_class->draw = gimp_color_wheel_draw; + widget_class->focus = gimp_color_wheel_focus; + widget_class->grab_broken_event = gimp_color_wheel_grab_broken; + + wheel_class->move = gimp_color_wheel_move; + + wheel_signals[CHANGED] = + g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GimpColorWheelClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + wheel_signals[MOVE] = + g_signal_new ("move", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GimpColorWheelClass, move), + NULL, NULL, + g_cclosure_marshal_VOID__ENUM, + G_TYPE_NONE, 1, + GTK_TYPE_DIRECTION_TYPE); + + binding_set = gtk_binding_set_by_class (class); + + gtk_binding_entry_add_signal (binding_set, GDK_KEY_Up, 0, + "move", 1, + G_TYPE_ENUM, GTK_DIR_UP); + gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Up, 0, + "move", 1, + G_TYPE_ENUM, GTK_DIR_UP); + + gtk_binding_entry_add_signal (binding_set, GDK_KEY_Down, 0, + "move", 1, + G_TYPE_ENUM, GTK_DIR_DOWN); + gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Down, 0, + "move", 1, + G_TYPE_ENUM, GTK_DIR_DOWN); + + + gtk_binding_entry_add_signal (binding_set, GDK_KEY_Right, 0, + "move", 1, + G_TYPE_ENUM, GTK_DIR_RIGHT); + gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Right, 0, + "move", 1, + G_TYPE_ENUM, GTK_DIR_RIGHT); + + gtk_binding_entry_add_signal (binding_set, GDK_KEY_Left, 0, + "move", 1, + G_TYPE_ENUM, GTK_DIR_LEFT); + gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Left, 0, + "move", 1, + G_TYPE_ENUM, GTK_DIR_LEFT); + + g_type_class_add_private (object_class, sizeof (GimpColorWheelPrivate)); +} + +static void +gimp_color_wheel_init (GimpColorWheel *wheel) +{ + GimpColorWheelPrivate *priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE (wheel, GIMP_TYPE_COLOR_WHEEL, + GimpColorWheelPrivate); + + wheel->priv = priv; + + gtk_widget_set_has_window (GTK_WIDGET (wheel), FALSE); + gtk_widget_set_can_focus (GTK_WIDGET (wheel), TRUE); + + priv->ring_fraction = DEFAULT_FRACTION; + priv->size = DEFAULT_SIZE; + priv->ring_width = DEFAULT_RING_WIDTH; +} + +static void +gimp_color_wheel_map (GtkWidget *widget) +{ + GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget); + GimpColorWheelPrivate *priv = wheel->priv; + + GTK_WIDGET_CLASS (parent_class)->map (widget); + + gdk_window_show (priv->window); +} + +static void +gimp_color_wheel_unmap (GtkWidget *widget) +{ + GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget); + GimpColorWheelPrivate *priv = wheel->priv; + + gdk_window_hide (priv->window); + + GTK_WIDGET_CLASS (parent_class)->unmap (widget); +} + +static void +gimp_color_wheel_realize (GtkWidget *widget) +{ + GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget); + GimpColorWheelPrivate *priv = wheel->priv; + GtkAllocation allocation; + GdkWindowAttr attr; + gint attr_mask; + GdkWindow *parent_window; + + gtk_widget_get_allocation (widget, &allocation); + + gtk_widget_set_realized (widget, TRUE); + + attr.window_type = GDK_WINDOW_CHILD; + attr.x = allocation.x; + attr.y = allocation.y; + attr.width = allocation.width; + attr.height = allocation.height; + attr.wclass = GDK_INPUT_ONLY; + attr.event_mask = (gtk_widget_get_events (widget) | + GDK_KEY_PRESS_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK); + + attr_mask = GDK_WA_X | GDK_WA_Y; + + parent_window = gtk_widget_get_parent_window (widget); + + gtk_widget_set_window (widget, parent_window); + g_object_ref (parent_window); + + priv->window = gdk_window_new (parent_window, &attr, attr_mask); + gdk_window_set_user_data (priv->window, wheel); +} + +static void +gimp_color_wheel_unrealize (GtkWidget *widget) +{ + GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget); + GimpColorWheelPrivate *priv = wheel->priv; + + gdk_window_set_user_data (priv->window, NULL); + gdk_window_destroy (priv->window); + priv->window = NULL; + + GTK_WIDGET_CLASS (parent_class)->unrealize (widget); +} + +static void +gimp_color_wheel_get_preferred_width (GtkWidget *widget, + gint *minimum_width, + gint *natural_width) +{ + gint focus_width; + gint focus_pad; + + gtk_widget_style_get (widget, + "focus-line-width", &focus_width, + "focus-padding", &focus_pad, + NULL); + + *minimum_width = *natural_width = DEFAULT_SIZE + 2 * (focus_width + focus_pad); +} + +static void +gimp_color_wheel_get_preferred_height (GtkWidget *widget, + gint *minimum_height, + gint *natural_height) +{ + gint focus_width; + gint focus_pad; + + gtk_widget_style_get (widget, + "focus-line-width", &focus_width, + "focus-padding", &focus_pad, + NULL); + + *minimum_height = *natural_height = DEFAULT_SIZE + 2 * (focus_width + focus_pad); +} + +static void +gimp_color_wheel_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget); + GimpColorWheelPrivate *priv = wheel->priv; + gint focus_width; + gint focus_pad; + + gtk_widget_set_allocation (widget, allocation); + + gtk_widget_style_get (widget, + "focus-line-width", &focus_width, + "focus-padding", &focus_pad, + NULL); + + priv->size = MIN (allocation->width - 2 * (focus_width + focus_pad), + allocation->height - 2 * (focus_width + focus_pad)); + + priv->ring_width = priv->size * priv->ring_fraction; + + if (gtk_widget_get_realized (widget)) + gdk_window_move_resize (priv->window, + allocation->x, + allocation->y, + allocation->width, + allocation->height); +} + + +/* Utility functions */ + +#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11) + +/* Converts from HSV to RGB */ +static void +hsv_to_rgb (gdouble *h, + gdouble *s, + gdouble *v) +{ + gdouble hue, saturation, value; + gdouble f, p, q, t; + + if (*s == 0.0) + { + *h = *v; + *s = *v; + *v = *v; /* heh */ + } + else + { + hue = *h * 6.0; + saturation = *s; + value = *v; + + if (hue == 6.0) + hue = 0.0; + + f = hue - (int) hue; + p = value * (1.0 - saturation); + q = value * (1.0 - saturation * f); + t = value * (1.0 - saturation * (1.0 - f)); + + switch ((int) hue) + { + case 0: + *h = value; + *s = t; + *v = p; + break; + + case 1: + *h = q; + *s = value; + *v = p; + break; + + case 2: + *h = p; + *s = value; + *v = t; + break; + + case 3: + *h = p; + *s = q; + *v = value; + break; + + case 4: + *h = t; + *s = p; + *v = value; + break; + + case 5: + *h = value; + *s = p; + *v = q; + break; + + default: + g_assert_not_reached (); + } + } +} + +/* Computes the vertices of the saturation/value triangle */ +static void +compute_triangle (GimpColorWheel *wheel, + gint *hx, + gint *hy, + gint *sx, + gint *sy, + gint *vx, + gint *vy) +{ + GimpColorWheelPrivate *priv = wheel->priv; + GtkAllocation allocation; + gdouble center_x; + gdouble center_y; + gdouble inner, outer; + gdouble angle; + + gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation); + + center_x = allocation.width / 2.0; + center_y = allocation.height / 2.0; + + outer = priv->size / 2.0; + inner = outer - priv->ring_width; + angle = priv->h * 2.0 * G_PI; + + *hx = floor (center_x + cos (angle) * inner + 0.5); + *hy = floor (center_y - sin (angle) * inner + 0.5); + *sx = floor (center_x + cos (angle + 2.0 * G_PI / 3.0) * inner + 0.5); + *sy = floor (center_y - sin (angle + 2.0 * G_PI / 3.0) * inner + 0.5); + *vx = floor (center_x + cos (angle + 4.0 * G_PI / 3.0) * inner + 0.5); + *vy = floor (center_y - sin (angle + 4.0 * G_PI / 3.0) * inner + 0.5); +} + +/* Computes whether a point is inside the hue ring */ +static gboolean +is_in_ring (GimpColorWheel *wheel, + gdouble x, + gdouble y) +{ + GimpColorWheelPrivate *priv = wheel->priv; + GtkAllocation allocation; + gdouble dx, dy, dist; + gdouble center_x; + gdouble center_y; + gdouble inner, outer; + + gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation); + + center_x = allocation.width / 2.0; + center_y = allocation.height / 2.0; + + outer = priv->size / 2.0; + inner = outer - priv->ring_width; + + dx = x - center_x; + dy = center_y - y; + dist = dx * dx + dy * dy; + + return (dist >= inner * inner && dist <= outer * outer); +} + +/* Computes a saturation/value pair based on the mouse coordinates */ +static void +compute_sv (GimpColorWheel *wheel, + gdouble x, + gdouble y, + gdouble *s, + gdouble *v) +{ + GtkAllocation allocation; + gint ihx, ihy, isx, isy, ivx, ivy; + gdouble hx, hy, sx, sy, vx, vy; + gdouble center_x; + gdouble center_y; + + gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation); + + compute_triangle (wheel, &ihx, &ihy, &isx, &isy, &ivx, &ivy); + + center_x = allocation.width / 2.0; + center_y = allocation.height / 2.0; + + hx = ihx - center_x; + hy = center_y - ihy; + sx = isx - center_x; + sy = center_y - isy; + vx = ivx - center_x; + vy = center_y - ivy; + x -= center_x; + y = center_y - y; + + if (vx * (x - sx) + vy * (y - sy) < 0.0) + { + *s = 1.0; + *v = (((x - sx) * (hx - sx) + (y - sy) * (hy-sy)) + / ((hx - sx) * (hx - sx) + (hy - sy) * (hy - sy))); + + if (*v < 0.0) + *v = 0.0; + else if (*v > 1.0) + *v = 1.0; + } + else if (hx * (x - sx) + hy * (y - sy) < 0.0) + { + *s = 0.0; + *v = (((x - sx) * (vx - sx) + (y - sy) * (vy - sy)) + / ((vx - sx) * (vx - sx) + (vy - sy) * (vy - sy))); + + if (*v < 0.0) + *v = 0.0; + else if (*v > 1.0) + *v = 1.0; + } + else if (sx * (x - hx) + sy * (y - hy) < 0.0) + { + *v = 1.0; + *s = (((x - vx) * (hx - vx) + (y - vy) * (hy - vy)) / + ((hx - vx) * (hx - vx) + (hy - vy) * (hy - vy))); + + if (*s < 0.0) + *s = 0.0; + else if (*s > 1.0) + *s = 1.0; + } + else + { + *v = (((x - sx) * (hy - vy) - (y - sy) * (hx - vx)) + / ((vx - sx) * (hy - vy) - (vy - sy) * (hx - vx))); + + if (*v<= 0.0) + { + *v = 0.0; + *s = 0.0; + } + else + { + if (*v > 1.0) + *v = 1.0; + + if (fabs (hy - vy) < fabs (hx - vx)) + *s = (x - sx - *v * (vx - sx)) / (*v * (hx - vx)); + else + *s = (y - sy - *v * (vy - sy)) / (*v * (hy - vy)); + + if (*s < 0.0) + *s = 0.0; + else if (*s > 1.0) + *s = 1.0; + } + } +} + +/* Computes whether a point is inside the saturation/value triangle */ +static gboolean +is_in_triangle (GimpColorWheel *wheel, + gdouble x, + gdouble y) +{ + gint hx, hy, sx, sy, vx, vy; + gdouble det, s, v; + + compute_triangle (wheel, &hx, &hy, &sx, &sy, &vx, &vy); + + det = (vx - sx) * (hy - sy) - (vy - sy) * (hx - sx); + + s = ((x - sx) * (hy - sy) - (y - sy) * (hx - sx)) / det; + v = ((vx - sx) * (y - sy) - (vy - sy) * (x - sx)) / det; + + return (s >= 0.0 && v >= 0.0 && s + v <= 1.0); +} + +/* Computes a value based on the mouse coordinates */ +static double +compute_v (GimpColorWheel *wheel, + gdouble x, + gdouble y) +{ + GtkAllocation allocation; + gdouble center_x; + gdouble center_y; + gdouble dx, dy; + gdouble angle; + + gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation); + + center_x = allocation.width / 2.0; + center_y = allocation.height / 2.0; + + dx = x - center_x; + dy = center_y - y; + + angle = atan2 (dy, dx); + if (angle < 0.0) + angle += 2.0 * G_PI; + + return angle / (2.0 * G_PI); +} + +static void +set_cross_grab (GimpColorWheel *wheel, + guint32 time) +{ + GimpColorWheelPrivate *priv = wheel->priv; + GdkCursor *cursor; + + cursor = + gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (wheel)), + GDK_CROSSHAIR); + + gdk_device_grab (gtk_get_current_event_device(), + priv->window, + GDK_OWNERSHIP_NONE, + FALSE, + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK | + GDK_BUTTON_RELEASE_MASK, + cursor, time); + g_object_unref (cursor); +} + +static gboolean gimp_color_wheel_grab_broken(GtkWidget *widget, GdkEventGrabBroken *event) +{ + (void)event; + GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget); + GimpColorWheelPrivate *priv = wheel->priv; + + priv->mode = DRAG_NONE; + + return TRUE; +} + +static gboolean +gimp_color_wheel_button_press (GtkWidget *widget, + GdkEventButton *event) +{ + GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget); + GimpColorWheelPrivate *priv = wheel->priv; + gdouble x, y; + + if (priv->mode != DRAG_NONE || event->button != 1) + return FALSE; + + x = event->x; + y = event->y; + + if (is_in_ring (wheel, x, y)) + { + priv->mode = DRAG_H; + set_cross_grab (wheel, event->time); + + gimp_color_wheel_set_color (wheel, + compute_v (wheel, x, y), + priv->s, + priv->v); + + gtk_widget_grab_focus (widget); + priv->focus_on_ring = TRUE; + + return TRUE; + } + + if (is_in_triangle (wheel, x, y)) + { + gdouble s, v; + + priv->mode = DRAG_SV; + set_cross_grab (wheel, event->time); + + compute_sv (wheel, x, y, &s, &v); + gimp_color_wheel_set_color (wheel, priv->h, s, v); + + gtk_widget_grab_focus (widget); + priv->focus_on_ring = FALSE; + + return TRUE; + } + + return FALSE; +} + +static gboolean +gimp_color_wheel_button_release (GtkWidget *widget, + GdkEventButton *event) +{ + GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget); + GimpColorWheelPrivate *priv = wheel->priv; + DragMode mode; + gdouble x, y; + + if (priv->mode == DRAG_NONE || event->button != 1) + return FALSE; + + /* Set the drag mode to DRAG_NONE so that signal handlers for "catched" + * can see that this is the final color state. + */ + + mode = priv->mode; + priv->mode = DRAG_NONE; + + x = event->x; + y = event->y; + + if (mode == DRAG_H) + { + gimp_color_wheel_set_color (wheel, + compute_v (wheel, x, y), priv->s, priv->v); + } + else if (mode == DRAG_SV) + { + gdouble s, v; + + compute_sv (wheel, x, y, &s, &v); + gimp_color_wheel_set_color (wheel, priv->h, s, v); + } + else + g_assert_not_reached (); + + gdk_device_ungrab (gtk_get_current_event_device(), + event->time); + + return TRUE; +} + +static gboolean +gimp_color_wheel_motion (GtkWidget *widget, + GdkEventMotion *event) +{ + GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget); + GimpColorWheelPrivate *priv = wheel->priv; + gdouble x, y; + + if (priv->mode == DRAG_NONE) + return FALSE; + + gdk_event_request_motions (event); + x = event->x; + y = event->y; + + if (priv->mode == DRAG_H) + { + gimp_color_wheel_set_color (wheel, + compute_v (wheel, x, y), priv->s, priv->v); + return TRUE; + } + else if (priv->mode == DRAG_SV) + { + gdouble s, v; + + compute_sv (wheel, x, y, &s, &v); + gimp_color_wheel_set_color (wheel, priv->h, s, v); + return TRUE; + } + + g_assert_not_reached (); + + return FALSE; +} + + +/* Redrawing */ + +/* Paints the hue ring */ +static void +paint_ring (GimpColorWheel *wheel, + cairo_t *cr) +{ + GtkWidget *widget = GTK_WIDGET (wheel); + GimpColorWheelPrivate *priv = wheel->priv; + gint width, height; + gint xx, yy; + gdouble dx, dy, dist; + gdouble center_x; + gdouble center_y; + gdouble inner, outer; + guint32 *buf, *p; + gdouble angle; + gdouble hue; + gdouble r, g, b; + cairo_surface_t *source; + cairo_t *source_cr; + gint stride; + + width = gtk_widget_get_allocated_width (widget); + height = gtk_widget_get_allocated_height (widget); + + center_x = width / 2.0; + center_y = height / 2.0; + + outer = priv->size / 2.0; + inner = outer - priv->ring_width; + + /* Create an image initialized with the ring colors */ + + stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, width); + buf = g_new (guint32, height * stride / 4); + + for (yy = 0; yy < height; yy++) + { + p = buf + yy * width; + dy = -(yy - center_y); + + for (xx = 0; xx < width; xx++) + { + dx = xx - center_x; + + dist = dx * dx + dy * dy; + if (dist < ((inner-1) * (inner-1)) || dist > ((outer+1) * (outer+1))) + { + *p++ = 0; + continue; + } + + angle = atan2 (dy, dx); + if (angle < 0.0) + angle += 2.0 * G_PI; + + hue = angle / (2.0 * G_PI); + + r = hue; + g = 1.0; + b = 1.0; + hsv_to_rgb (&r, &g, &b); + + *p++ = (((int)floor (r * 255 + 0.5) << 16) | + ((int)floor (g * 255 + 0.5) << 8) | + (int)floor (b * 255 + 0.5)); + } + } + + source = cairo_image_surface_create_for_data ((unsigned char *)buf, + CAIRO_FORMAT_RGB24, + width, height, stride); + + /* Now draw the value marker onto the source image, so that it + * will get properly clipped at the edges of the ring + */ + source_cr = cairo_create (source); + + r = priv->h; + g = 1.0; + b = 1.0; + hsv_to_rgb (&r, &g, &b); + + if (INTENSITY (r, g, b) > 0.5) + cairo_set_source_rgb (source_cr, 0.0, 0.0, 0.0); + else + cairo_set_source_rgb (source_cr, 1.0, 1.0, 1.0); + + cairo_move_to (source_cr, center_x, center_y); + cairo_line_to (source_cr, + center_x + cos (priv->h * 2.0 * G_PI) * priv->size / 2, + center_y - sin (priv->h * 2.0 * G_PI) * priv->size / 2); + cairo_stroke (source_cr); + cairo_destroy (source_cr); + + /* Draw the ring using the source image */ + + cairo_save (cr); + + cairo_set_source_surface (cr, source, 0, 0); + cairo_surface_destroy (source); + + cairo_set_line_width (cr, priv->ring_width); + cairo_new_path (cr); + cairo_arc (cr, + center_x, center_y, + priv->size / 2.0 - priv->ring_width / 2.0, + 0, 2 * G_PI); + cairo_stroke (cr); + + cairo_restore (cr); + + g_free (buf); +} + +/* Converts an HSV triplet to an integer RGB triplet */ +static void +get_color (gdouble h, + gdouble s, + gdouble v, + gint *r, + gint *g, + gint *b) +{ + hsv_to_rgb (&h, &s, &v); + + *r = floor (h * 255 + 0.5); + *g = floor (s * 255 + 0.5); + *b = floor (v * 255 + 0.5); +} + +#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t)) + +#define LERP(a, b, v1, v2, i) (((v2) - (v1) != 0) \ + ? ((a) + ((b) - (a)) * ((i) - (v1)) / ((v2) - (v1))) \ + : (a)) + +/* Number of pixels we extend out from the edges when creating + * color source to avoid artifacts + */ +#define PAD 3 + +/* Paints the HSV triangle */ +static void +paint_triangle (GimpColorWheel *wheel, + cairo_t *cr, + gboolean draw_focus) +{ + GtkWidget *widget = GTK_WIDGET (wheel); + GimpColorWheelPrivate *priv = wheel->priv; + gint hx, hy, sx, sy, vx, vy; /* HSV vertices */ + gint x1, y1, r1, g1, b1; /* First vertex in scanline order */ + gint x2, y2, r2, g2, b2; /* Second vertex */ + gint x3, y3, r3, g3, b3; /* Third vertex */ + gint t; + guint32 *buf, *p, c; + gint xl, xr, rl, rr, gl, gr, bl, br; /* Scanline data */ + gint xx, yy; + gint x_interp, y_interp; + gint x_start, x_end; + cairo_surface_t *source; + gdouble r, g, b; + gint stride; + gint width, height; + GtkStyleContext *context; + + width = gtk_widget_get_allocated_width (widget); + height = gtk_widget_get_allocated_height (widget); + + /* Compute triangle's vertices */ + + compute_triangle (wheel, &hx, &hy, &sx, &sy, &vx, &vy); + + x1 = hx; + y1 = hy; + get_color (priv->h, 1.0, 1.0, &r1, &g1, &b1); + + x2 = sx; + y2 = sy; + get_color (priv->h, 1.0, 0.0, &r2, &g2, &b2); + + x3 = vx; + y3 = vy; + get_color (priv->h, 0.0, 1.0, &r3, &g3, &b3); + + if (y2 > y3) + { + SWAP (x2, x3, t); + SWAP (y2, y3, t); + SWAP (r2, r3, t); + SWAP (g2, g3, t); + SWAP (b2, b3, t); + } + + if (y1 > y3) + { + SWAP (x1, x3, t); + SWAP (y1, y3, t); + SWAP (r1, r3, t); + SWAP (g1, g3, t); + SWAP (b1, b3, t); + } + + if (y1 > y2) + { + SWAP (x1, x2, t); + SWAP (y1, y2, t); + SWAP (r1, r2, t); + SWAP (g1, g2, t); + SWAP (b1, b2, t); + } + + /* Shade the triangle */ + + stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, width); + buf = g_new (guint32, height * stride / 4); + + for (yy = 0; yy < height; yy++) + { + p = buf + yy * width; + + if (yy >= y1 - PAD && yy < y3 + PAD) + { + y_interp = CLAMP (yy, y1, y3); + + if (y_interp < y2) + { + xl = LERP (x1, x2, y1, y2, y_interp); + + rl = LERP (r1, r2, y1, y2, y_interp); + gl = LERP (g1, g2, y1, y2, y_interp); + bl = LERP (b1, b2, y1, y2, y_interp); + } + else + { + xl = LERP (x2, x3, y2, y3, y_interp); + + rl = LERP (r2, r3, y2, y3, y_interp); + gl = LERP (g2, g3, y2, y3, y_interp); + bl = LERP (b2, b3, y2, y3, y_interp); + } + + xr = LERP (x1, x3, y1, y3, y_interp); + + rr = LERP (r1, r3, y1, y3, y_interp); + gr = LERP (g1, g3, y1, y3, y_interp); + br = LERP (b1, b3, y1, y3, y_interp); + + if (xl > xr) + { + SWAP (xl, xr, t); + SWAP (rl, rr, t); + SWAP (gl, gr, t); + SWAP (bl, br, t); + } + + x_start = MAX (xl - PAD, 0); + x_end = MIN (xr + PAD, width); + x_start = MIN (x_start, x_end); + + c = (rl << 16) | (gl << 8) | bl; + + for (xx = 0; xx < x_start; xx++) + *p++ = c; + + for (; xx < x_end; xx++) + { + x_interp = CLAMP (xx, xl, xr); + + *p++ = ((LERP (rl, rr, xl, xr, x_interp) << 16) | + (LERP (gl, gr, xl, xr, x_interp) << 8) | + LERP (bl, br, xl, xr, x_interp)); + } + + c = (rr << 16) | (gr << 8) | br; + + for (; xx < width; xx++) + *p++ = c; + } + } + + source = cairo_image_surface_create_for_data ((unsigned char *)buf, + CAIRO_FORMAT_RGB24, + width, height, stride); + + /* Draw a triangle with the image as a source */ + + cairo_set_source_surface (cr, source, 0, 0); + cairo_surface_destroy (source); + + cairo_move_to (cr, x1, y1); + cairo_line_to (cr, x2, y2); + cairo_line_to (cr, x3, y3); + cairo_close_path (cr); + cairo_fill (cr); + + g_free (buf); + + /* Draw value marker */ + + xx = floor (sx + (vx - sx) * priv->v + (hx - vx) * priv->s * priv->v + 0.5); + yy = floor (sy + (vy - sy) * priv->v + (hy - vy) * priv->s * priv->v + 0.5); + + r = priv->h; + g = priv->s; + b = priv->v; + hsv_to_rgb (&r, &g, &b); + + context = gtk_widget_get_style_context (widget); + + gtk_style_context_save (context); + + if (INTENSITY (r, g, b) > 0.5) + { + gtk_style_context_add_class (context, "light-area-focus"); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); + } + else + { + gtk_style_context_add_class (context, "dark-area-focus"); + cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); + } + +#define RADIUS 4 +#define FOCUS_RADIUS 6 + + cairo_new_path (cr); + cairo_arc (cr, xx, yy, RADIUS, 0, 2 * G_PI); + cairo_stroke (cr); + + /* Draw focus outline */ + + if (draw_focus && ! priv->focus_on_ring) + { + gint focus_width; + gint focus_pad; + + gtk_widget_style_get (widget, + "focus-line-width", &focus_width, + "focus-padding", &focus_pad, + NULL); + + gtk_render_focus (context, cr, + xx - FOCUS_RADIUS - focus_width - focus_pad, + yy - FOCUS_RADIUS - focus_width - focus_pad, + 2 * (FOCUS_RADIUS + focus_width + focus_pad), + 2 * (FOCUS_RADIUS + focus_width + focus_pad)); + } + + gtk_style_context_restore (context); +} + +static gboolean +gimp_color_wheel_draw (GtkWidget *widget, + cairo_t *cr) +{ + GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget); + GimpColorWheelPrivate *priv = wheel->priv; + gboolean draw_focus; + + draw_focus = gtk_widget_has_visible_focus (widget); + + paint_ring (wheel, cr); + paint_triangle (wheel, cr, draw_focus); + + if (draw_focus && priv->focus_on_ring) + { + GtkStyleContext *context = gtk_widget_get_style_context (widget); + + gtk_render_focus (context, cr, 0, 0, + gtk_widget_get_allocated_width (widget), + gtk_widget_get_allocated_height (widget)); + } + + return FALSE; +} + +static gboolean +gimp_color_wheel_focus (GtkWidget *widget, + GtkDirectionType dir) +{ + GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget); + GimpColorWheelPrivate *priv = wheel->priv; + + if (!gtk_widget_has_focus (widget)) + { + if (dir == GTK_DIR_TAB_BACKWARD) + priv->focus_on_ring = FALSE; + else + priv->focus_on_ring = TRUE; + + gtk_widget_grab_focus (widget); + return TRUE; + } + + switch (dir) + { + case GTK_DIR_UP: + if (priv->focus_on_ring) + return FALSE; + else + priv->focus_on_ring = TRUE; + break; + + case GTK_DIR_DOWN: + if (priv->focus_on_ring) + priv->focus_on_ring = FALSE; + else + return FALSE; + break; + + case GTK_DIR_LEFT: + case GTK_DIR_TAB_BACKWARD: + if (priv->focus_on_ring) + return FALSE; + else + priv->focus_on_ring = TRUE; + break; + + case GTK_DIR_RIGHT: + case GTK_DIR_TAB_FORWARD: + if (priv->focus_on_ring) + priv->focus_on_ring = FALSE; + else + return FALSE; + break; + } + + gtk_widget_queue_draw (widget); + + return TRUE; +} + +/** + * gimp_color_wheel_new: + * + * Creates a new HSV color selector. + * + * Return value: A newly-created HSV color selector. + * + * Since: 2.14 + */ +GtkWidget* +gimp_color_wheel_new (void) +{ + return g_object_new (GIMP_TYPE_COLOR_WHEEL, NULL); +} + +/** + * gimp_color_wheel_set_color: + * @hsv: An HSV color selector + * @h: Hue + * @s: Saturation + * @v: Value + * + * Sets the current color in an HSV color selector. + * Color component values must be in the [0.0, 1.0] range. + * + * Since: 2.14 + */ +void +gimp_color_wheel_set_color (GimpColorWheel *wheel, + gdouble h, + gdouble s, + gdouble v) +{ + GimpColorWheelPrivate *priv; + + g_return_if_fail (GIMP_IS_COLOR_WHEEL (wheel)); + g_return_if_fail (h >= 0.0 && h <= 1.0); + g_return_if_fail (s >= 0.0 && s <= 1.0); + g_return_if_fail (v >= 0.0 && v <= 1.0); + + priv = wheel->priv; + + if(h == 0.0 && s == 0.0) { + h = priv->h; + } + + priv->h = h; + priv->s = s; + priv->v = v; + + g_signal_emit (wheel, wheel_signals[CHANGED], 0); + + gtk_widget_queue_draw (GTK_WIDGET (wheel)); +} + +/** + * gimp_color_wheel_get_color: + * @hsv: An HSV color selector + * @h: (out): Return value for the hue + * @s: (out): Return value for the saturation + * @v: (out): Return value for the value + * + * Queries the current color in an HSV color selector. + * Returned values will be in the [0.0, 1.0] range. + * + * Since: 2.14 + */ +void +gimp_color_wheel_get_color (GimpColorWheel *wheel, + gdouble *h, + gdouble *s, + gdouble *v) +{ + GimpColorWheelPrivate *priv; + + g_return_if_fail (GIMP_IS_COLOR_WHEEL (wheel)); + + priv = wheel->priv; + + if (h) *h = priv->h; + if (s) *s = priv->s; + if (v) *v = priv->v; +} + +/** + * gimp_color_wheel_set_ring_fraction: + * @ring: A wheel color selector + * @fraction: Ring fraction + * + * Sets the ring fraction of a wheel color selector. + * + * Since: GIMP 2.10 + */ +void +gimp_color_wheel_set_ring_fraction (GimpColorWheel *hsv, + gdouble fraction) +{ + GimpColorWheelPrivate *priv; + + g_return_if_fail (GIMP_IS_COLOR_WHEEL (hsv)); + + priv = hsv->priv; + + priv->ring_fraction = CLAMP (fraction, 0.01, 0.99); + + gtk_widget_queue_draw (GTK_WIDGET (hsv)); +} + +/** + * gimp_color_wheel_get_ring_fraction: + * @ring: A wheel color selector + * + * Returns value: The ring fraction of the wheel color selector. + * + * Since: GIMP 2.10 + */ +gdouble +gimp_color_wheel_get_ring_fraction (GimpColorWheel *wheel) +{ + GimpColorWheelPrivate *priv; + + g_return_val_if_fail (GIMP_IS_COLOR_WHEEL (wheel), DEFAULT_FRACTION); + + priv = wheel->priv; + + return priv->ring_fraction; +} + +/** + * gimp_color_wheel_is_adjusting: + * @hsv: A #GimpColorWheel + * + * An HSV color selector can be said to be adjusting if multiple rapid + * changes are being made to its value, for example, when the user is + * adjusting the value with the mouse. This function queries whether + * the HSV color selector is being adjusted or not. + * + * Return value: %TRUE if clients can ignore changes to the color value, + * since they may be transitory, or %FALSE if they should consider + * the color value status to be final. + * + * Since: 2.14 + */ +gboolean +gimp_color_wheel_is_adjusting (GimpColorWheel *wheel) +{ + GimpColorWheelPrivate *priv; + + g_return_val_if_fail (GIMP_IS_COLOR_WHEEL (wheel), FALSE); + + priv = wheel->priv; + + return priv->mode != DRAG_NONE; +} + +static void +gimp_color_wheel_move (GimpColorWheel *wheel, + GtkDirectionType dir) +{ + GimpColorWheelPrivate *priv = wheel->priv; + gdouble hue, sat, val; + gint hx, hy, sx, sy, vx, vy; /* HSV vertices */ + gint x, y; /* position in triangle */ + + hue = priv->h; + sat = priv->s; + val = priv->v; + + compute_triangle (wheel, &hx, &hy, &sx, &sy, &vx, &vy); + + x = floor (sx + (vx - sx) * priv->v + (hx - vx) * priv->s * priv->v + 0.5); + y = floor (sy + (vy - sy) * priv->v + (hy - vy) * priv->s * priv->v + 0.5); + +#define HUE_DELTA 0.002 + switch (dir) + { + case GTK_DIR_UP: + if (priv->focus_on_ring) + hue += HUE_DELTA; + else + { + y -= 1; + compute_sv (wheel, x, y, &sat, &val); + } + break; + + case GTK_DIR_DOWN: + if (priv->focus_on_ring) + hue -= HUE_DELTA; + else + { + y += 1; + compute_sv (wheel, x, y, &sat, &val); + } + break; + + case GTK_DIR_LEFT: + if (priv->focus_on_ring) + hue += HUE_DELTA; + else + { + x -= 1; + compute_sv (wheel, x, y, &sat, &val); + } + break; + + case GTK_DIR_RIGHT: + if (priv->focus_on_ring) + hue -= HUE_DELTA + ; + else + { + x += 1; + compute_sv (wheel, x, y, &sat, &val); + } + break; + + default: + /* we don't care about the tab directions */ + break; + } + + /* Wrap */ + if (hue < 0.0) + hue = 1.0; + else if (hue > 1.0) + hue = 0.0; + + gimp_color_wheel_set_color (wheel, hue, sat, val); +} diff --git a/src/widgets/gimp/gimpcolorwheel.h b/src/widgets/gimp/gimpcolorwheel.h new file mode 100644 index 000000000..016fb593f --- /dev/null +++ b/src/widgets/gimp/gimpcolorwheel.h @@ -0,0 +1,95 @@ +/* HSV color selector for GTK+ + * + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Simon Budig <Simon.Budig@unix-ag.org> (original code) + * Federico Mena-Quintero <federico@gimp.org> (cleanup for GTK+) + * Jonathan Blandford <jrb@redhat.com> (cleanup for GTK+) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __GIMP_COLOR_WHEEL_H__ +#define __GIMP_COLOR_WHEEL_H__ + +G_BEGIN_DECLS + +#define GIMP_TYPE_COLOR_WHEEL (gimp_color_wheel_get_type ()) +#define GIMP_COLOR_WHEEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_COLOR_WHEEL, GimpColorWheel)) +#define GIMP_COLOR_WHEEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_COLOR_WHEEL, GimpColorWheelClass)) +#define GIMP_IS_COLOR_WHEEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_COLOR_WHEEL)) +#define GIMP_IS_COLOR_WHEEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_COLOR_WHEEL)) +#define GIMP_COLOR_WHEEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_COLOR_WHEEL, GimpColorWheelClass)) + + +typedef struct _GimpColorWheel GimpColorWheel; +typedef struct _GimpColorWheelClass GimpColorWheelClass; + +struct _GimpColorWheel +{ + GtkWidget parent_instance; + + /* Private data */ + gpointer priv; +}; + +struct _GimpColorWheelClass +{ + GtkWidgetClass parent_class; + + /* Notification signals */ + void (* changed) (GimpColorWheel *wheel); + + /* Keybindings */ + void (* move) (GimpColorWheel *wheel, + GtkDirectionType type); + + /* Padding for future expansion */ + void (*_gimp_reserved1) (void); + void (*_gimp_reserved2) (void); + void (*_gimp_reserved3) (void); + void (*_gimp_reserved4) (void); +}; + + +GType gimp_color_wheel_get_type (void) G_GNUC_CONST; +GtkWidget * gimp_color_wheel_new (void); + +void gimp_color_wheel_set_color (GimpColorWheel *wheel, + double h, + double s, + double v); +void gimp_color_wheel_get_color (GimpColorWheel *wheel, + gdouble *h, + gdouble *s, + gdouble *v); + +void gimp_color_wheel_set_ring_fraction (GimpColorWheel *wheel, + gdouble fraction); +gdouble gimp_color_wheel_get_ring_fraction (GimpColorWheel *wheel); + +gboolean gimp_color_wheel_is_adjusting (GimpColorWheel *wheel); + +G_END_DECLS + +#endif /* __GIMP_COLOR_WHEEL_H__ */ diff --git a/src/widgets/gimp/gimpspinscale.c b/src/widgets/gimp/gimpspinscale.c new file mode 100644 index 000000000..8d8c6c935 --- /dev/null +++ b/src/widgets/gimp/gimpspinscale.c @@ -0,0 +1,969 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpspinscale.c + * Copyright (C) 2010 Michael Natterer <mitch@gimp.org> + * 2012 Øyvind Kolås <pippin@gimp.org> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <math.h> +#include <string.h> +#include <gdk/gdkkeysyms.h> + +#include "gimpspinscale.h" + + +enum +{ + PROP_0, + PROP_LABEL, + PROP_FOCUS_WIDGET +}; + +typedef enum +{ + TARGET_NUMBER, + TARGET_UPPER, + TARGET_LOWER, + TARGET_NONE +} SpinScaleTarget; + +typedef enum +{ + APPEARANCE_FULL = 1, /* Full size suitable for tablets */ + APPEARANCE_COMPACT, /* Compact, suitable for desktops with mouse control */ +} SpinScaleAppearance; + +typedef struct _GimpSpinScalePrivate GimpSpinScalePrivate; + +struct _GimpSpinScalePrivate +{ + gchar *label; + + gboolean scale_limits_set; + gdouble scale_lower; + gdouble scale_upper; + gdouble gamma; + + PangoLayout *layout; + gboolean changing_value; + gboolean relative_change; + gdouble start_x; + gdouble start_value; + + GtkWidget* focusWidget; + gboolean transferFocus; + SpinScaleAppearance appearanceMode; +}; + +#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ + GIMP_TYPE_SPIN_SCALE, \ + GimpSpinScalePrivate)) + + +static void gimp_spin_scale_dispose (GObject *object); +static void gimp_spin_scale_finalize (GObject *object); +static void gimp_spin_scale_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_spin_scale_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static void gimp_spin_scale_style_set (GtkWidget *widget, + GtkStyle *prev_style); + +static void gimp_spin_scale_get_preferred_width (GtkWidget *widget, + gint *minimum_width, + gint *natural_width); +static void gimp_spin_scale_get_preferred_height (GtkWidget *widget, + gint *minimum_width, + gint *natural_width); +static gboolean gimp_spin_scale_draw (GtkWidget *widget, + cairo_t *cr); + +static gboolean gimp_spin_scale_button_press (GtkWidget *widget, + GdkEventButton *event); +static gboolean gimp_spin_scale_button_release (GtkWidget *widget, + GdkEventButton *event); +static gboolean gimp_spin_scale_motion_notify (GtkWidget *widget, + GdkEventMotion *event); +static gboolean gimp_spin_scale_leave_notify (GtkWidget *widget, + GdkEventCrossing *event); +static gboolean gimp_spin_scale_keypress( GtkWidget *widget, + GdkEventKey *event); + +static void gimp_spin_scale_defocus( GtkSpinButton *spin_button ); + +static void gimp_spin_scale_value_changed (GtkSpinButton *spin_button); + + +G_DEFINE_TYPE (GimpSpinScale, gimp_spin_scale, GTK_TYPE_SPIN_BUTTON); + +#define parent_class gimp_spin_scale_parent_class + + +static void +gimp_spin_scale_class_init (GimpSpinScaleClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkSpinButtonClass *spin_button_class = GTK_SPIN_BUTTON_CLASS (klass); + + object_class->dispose = gimp_spin_scale_dispose; + object_class->finalize = gimp_spin_scale_finalize; + object_class->set_property = gimp_spin_scale_set_property; + object_class->get_property = gimp_spin_scale_get_property; + + widget_class->style_set = gimp_spin_scale_style_set; + widget_class->get_preferred_width = gimp_spin_scale_get_preferred_width; + widget_class->get_preferred_height = gimp_spin_scale_get_preferred_height; + widget_class->draw = gimp_spin_scale_draw; + widget_class->button_press_event = gimp_spin_scale_button_press; + widget_class->button_release_event = gimp_spin_scale_button_release; + widget_class->motion_notify_event = gimp_spin_scale_motion_notify; + widget_class->leave_notify_event = gimp_spin_scale_leave_notify; + widget_class->key_press_event = gimp_spin_scale_keypress; + + spin_button_class->value_changed = gimp_spin_scale_value_changed; + + g_object_class_install_property (object_class, PROP_LABEL, + g_param_spec_string ("label", NULL, NULL, + NULL, + G_PARAM_READWRITE)); + + g_type_class_add_private (klass, sizeof (GimpSpinScalePrivate)); +} + +static void +gimp_spin_scale_init (GimpSpinScale *scale) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (scale); + + gtk_widget_add_events (GTK_WIDGET (scale), + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_BUTTON1_MOTION_MASK | + GDK_LEAVE_NOTIFY_MASK); + + gtk_entry_set_alignment (GTK_ENTRY (scale), 1.0); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (scale), TRUE); + + private->gamma = 1.0; + private->focusWidget = NULL; + private->transferFocus = FALSE; + private->appearanceMode = APPEARANCE_COMPACT; +} + +static void +gimp_spin_scale_dispose (GObject *object) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (object); + + if (private->layout) + { + g_object_unref (private->layout); + private->layout = NULL; + } + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gimp_spin_scale_finalize (GObject *object) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (object); + + if (private->label) + { + g_free (private->label); + private->label = NULL; + } + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gimp_spin_scale_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (object); + GimpSpinScale *scale = GIMP_SPIN_SCALE (object); + + switch (property_id) + { + case PROP_LABEL: + gimp_spin_scale_set_label (scale, g_value_get_string (value)); + break; + + case PROP_FOCUS_WIDGET: + { + /* TODO unhook prior */ + private->focusWidget = GTK_WIDGET (g_value_get_pointer (value)); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_spin_scale_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (object); + GimpSpinScale *scale = GIMP_SPIN_SCALE (object); + + switch (property_id) + { + case PROP_LABEL: + g_value_set_string (value, gimp_spin_scale_get_label (scale)); + break; + + case PROP_FOCUS_WIDGET: + g_value_set_pointer (value, private->focusWidget); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + + +void +gimp_spin_scale_set_focuswidget( GtkWidget *scale, GtkWidget* widget ) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (scale); + + /* TODO unhook prior */ + + private->focusWidget = widget; +} + +void +gimp_spin_scale_set_appearance( GtkWidget *widget, const gchar *appearance) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + + if ( strcmp("full", appearance) == 0 ) { + private->appearanceMode = APPEARANCE_FULL; + } else if ( strcmp("compact", appearance) == 0 ) { + private->appearanceMode = APPEARANCE_COMPACT; + } +} + +static void +gimp_spin_scale_get_preferred_width (GtkWidget *widget, + gint *minimum_width, + gint *natural_width) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + PangoContext *context = gtk_widget_get_pango_context (widget); + PangoFontMetrics *metrics; + + GTK_WIDGET_CLASS (parent_class)->get_preferred_width (widget, + minimum_width, + natural_width); + + metrics = pango_context_get_metrics (context, + pango_context_get_font_description (context), + pango_context_get_language (context)); + + if (private->label) + { + gint char_width; + gint digit_width; + gint char_pixels; + + char_width = pango_font_metrics_get_approximate_char_width (metrics); + digit_width = pango_font_metrics_get_approximate_digit_width (metrics); + char_pixels = PANGO_PIXELS (MAX (char_width, digit_width)); + + /* ~3 chars for the ellipse */ + *minimum_width += char_pixels * 3; + *natural_width += char_pixels * 3; + } + + pango_font_metrics_unref (metrics); +} + +static void +gimp_spin_scale_get_preferred_height (GtkWidget *widget, + gint *minimum_height, + gint *natural_height) +{ + PangoContext *context = gtk_widget_get_pango_context (widget); + PangoFontMetrics *metrics; + //gint height; + + GTK_WIDGET_CLASS (parent_class)->get_preferred_height (widget, + minimum_height, + natural_height); + + metrics = pango_context_get_metrics (context, + pango_context_get_font_description (context), + pango_context_get_language (context)); + + //height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) + + // pango_font_metrics_get_descent (metrics)); + + *minimum_height += 1; + *natural_height += 1; + + pango_font_metrics_unref (metrics); +} + +static void +gimp_spin_scale_style_set (GtkWidget *widget, + GtkStyle *prev_style) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + + GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style); + + if (private->layout) + { + g_object_unref (private->layout); + private->layout = NULL; + } +} + + +static gboolean + gimp_spin_scale_draw (GtkWidget *widget, + cairo_t *cr) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + GtkStyleContext *style = gtk_widget_get_style_context(widget); + GtkAllocation allocation; + GdkRGBA color; + + cairo_save (cr); + GTK_WIDGET_CLASS (parent_class)->draw (widget, cr); + cairo_restore (cr); + + gtk_widget_get_allocation (widget, &allocation); + + cairo_set_line_width (cr, 1.0); + + if (private->label) + { + GdkRectangle text_area; + gint minimum_width; + gint natural_width; + PangoRectangle logical; + gint layout_offset_x; + gint layout_offset_y; + GtkStateFlags state; + GdkRGBA text_color; + GdkRGBA bar_text_color; + gdouble progress_fraction; + gint progress_x; + gint progress_y; + gint progress_width; + gint progress_height; + + gtk_entry_get_text_area (GTK_ENTRY (widget), &text_area); + + GTK_WIDGET_CLASS (parent_class)->get_preferred_width (widget, + &minimum_width, + &natural_width); + + if (! private->layout) + { + private->layout = gtk_widget_create_pango_layout (widget, + private->label); + pango_layout_set_ellipsize (private->layout, PANGO_ELLIPSIZE_END); + } + + pango_layout_set_width (private->layout, + PANGO_SCALE * + (allocation.width - minimum_width)); + pango_layout_get_pixel_extents (private->layout, NULL, &logical); + + gtk_entry_get_layout_offsets (GTK_ENTRY (widget), NULL, &layout_offset_y); + + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + layout_offset_x = text_area.x + text_area.width - logical.width - 4; + else + layout_offset_x = 4; + + layout_offset_x -= logical.x; + + state = gtk_widget_get_state_flags (widget); + + gtk_style_context_get_color (style, state, &text_color); + + gtk_style_context_save (style); + gtk_style_context_add_class (style, GTK_STYLE_CLASS_PROGRESSBAR); + gtk_style_context_get_color (style, state, &bar_text_color); + gtk_style_context_restore (style); + + progress_fraction = gtk_entry_get_progress_fraction (GTK_ENTRY (widget)); + + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + { + progress_fraction = 1.0 - progress_fraction; + + progress_x = text_area.width * progress_fraction; + progress_y = 0; + progress_width = text_area.width - progress_x; + progress_height = text_area.height; + } + else + { + progress_x = 0; + progress_y = 0; + progress_width = text_area.width * progress_fraction; + progress_height = text_area.height; + } + + cairo_save (cr); + + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); + cairo_rectangle (cr, 0, 0, text_area.width, text_area.height); + cairo_rectangle (cr, progress_x, progress_y, + progress_width, progress_height); + cairo_clip (cr); + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING); + + cairo_move_to (cr, layout_offset_x, text_area.y + layout_offset_y-3); + gdk_cairo_set_source_rgba (cr, &text_color); + pango_cairo_show_layout (cr, private->layout); + cairo_restore (cr); + + cairo_rectangle (cr, progress_x, progress_y, + progress_width, progress_height); + cairo_clip (cr); + + cairo_move_to (cr, layout_offset_x, text_area.y + layout_offset_y-3); + gdk_cairo_set_source_rgba (cr, &bar_text_color); + pango_cairo_show_layout (cr, private->layout); + } + + return FALSE; +} + +/* Returns TRUE if a translation should be done */ +static gboolean +gtk_widget_get_translation_to_window (GtkWidget *widget, + GdkWindow *window, + int *x, + int *y) +{ + GdkWindow *w, *widget_window; + + if (!gtk_widget_get_has_window (widget)) + { + GtkAllocation allocation; + + gtk_widget_get_allocation (widget, &allocation); + + *x = -allocation.x; + *y = -allocation.y; + } + else + { + *x = 0; + *y = 0; + } + + widget_window = gtk_widget_get_window (widget); + + for (w = window; w && w != widget_window; w = gdk_window_get_parent (w)) + { + int wx, wy; + gdk_window_get_position (w, &wx, &wy); + *x += wx; + *y += wy; + } + + if (w == NULL) + { + *x = 0; + *y = 0; + return FALSE; + } + + return TRUE; +} + +static void +gimp_spin_scale_event_to_widget_coords (GtkWidget *widget, + GdkWindow *window, + gdouble event_x, + gdouble event_y, + gint *widget_x, + gint *widget_y) +{ + gint tx, ty; + + if (gtk_widget_get_translation_to_window (widget, window, &tx, &ty)) + { + event_x += tx; + event_y += ty; + } + + *widget_x = event_x; + *widget_y = event_y; +} + +static SpinScaleTarget +gimp_spin_scale_get_target (GtkWidget *widget, + gdouble x, + gdouble y) +{ + GtkAllocation allocation; + PangoRectangle logical; + gint layout_x; + gint layout_y; + + gtk_widget_get_allocation (widget, &allocation); + gtk_entry_get_layout_offsets (GTK_ENTRY (widget), &layout_x, &layout_y); + pango_layout_get_pixel_extents (gtk_entry_get_layout (GTK_ENTRY (widget)), + NULL, &logical); + + GdkRectangle text_area; + gtk_entry_get_text_area (GTK_ENTRY (widget), &text_area); + + if (x >= text_area.x && x < text_area.width && + y >= text_area.y && y < text_area.height) + { + x -= text_area.x; + y -= text_area.y; + + if (x > layout_x && x < layout_x + logical.width && + y > layout_y && y < layout_y + logical.height) + { + return TARGET_NUMBER; + } + else if (y > text_area.height / 2) + { + return TARGET_LOWER; + } + + return TARGET_UPPER; + } + + return TARGET_NONE; +} + +static void +gimp_spin_scale_get_limits (GimpSpinScale *scale, + gdouble *lower, + gdouble *upper) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (scale); + + if (private->scale_limits_set) + { + *lower = private->scale_lower; + *upper = private->scale_upper; + } + else + { + GtkSpinButton *spin_button = GTK_SPIN_BUTTON (scale); + GtkAdjustment *adjustment = gtk_spin_button_get_adjustment (spin_button); + + *lower = gtk_adjustment_get_lower (adjustment); + *upper = gtk_adjustment_get_upper (adjustment); + } +} + +static void +gimp_spin_scale_change_value (GtkWidget *widget, + gdouble x) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + GtkSpinButton *spin_button = GTK_SPIN_BUTTON (widget); + GtkAdjustment *adjustment = gtk_spin_button_get_adjustment (spin_button); + gdouble lower; + gdouble upper; + gdouble value; + GdkRectangle text_area; + gtk_entry_get_text_area (GTK_ENTRY (widget), &text_area); + gimp_spin_scale_get_limits (GIMP_SPIN_SCALE (widget), &lower, &upper); + + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + x = text_area.width - x; + + if (private->relative_change) + { + gdouble diff; + gdouble step; + + step = (upper - lower) / text_area.width / 10.0; + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + diff = x - (text_area.width - private->start_x); + else + diff = x - private->start_x; + + value = (private->start_value + diff * step); + } + else + { + gdouble fraction; + + fraction = x / (gdouble) text_area.width; + if (fraction > 0.0) + fraction = pow (fraction, private->gamma); + + value = fraction * (upper - lower) + lower; + } + + gtk_adjustment_set_value (adjustment, value); +} + +static gboolean +gimp_spin_scale_button_press (GtkWidget *widget, + GdkEventButton *event) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + + private->changing_value = FALSE; + private->relative_change = FALSE; + + gint x, y; + gimp_spin_scale_event_to_widget_coords (widget, event->window, + event->x, event->y, + &x, &y); + switch (gimp_spin_scale_get_target (widget, x, y)) + { + case TARGET_UPPER: + private->changing_value = TRUE; + + gtk_widget_grab_focus (widget); + + gimp_spin_scale_change_value (widget, x); + + return TRUE; + + case TARGET_LOWER: + private->changing_value = TRUE; + + gtk_widget_grab_focus (widget); + + private->relative_change = TRUE; + private->start_x = x; + private->start_value = gtk_adjustment_get_value (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget))); + + return TRUE; + + default: + break; + } + + return GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, event); +} + +static gboolean +gimp_spin_scale_button_release (GtkWidget *widget, + GdkEventButton *event) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + gint x, y; + + gimp_spin_scale_event_to_widget_coords (widget, event->window, + event->x, event->y, + &x, &y); + + if (private->changing_value) + { + private->changing_value = FALSE; + gimp_spin_scale_change_value (widget, x); + return TRUE; + } + + return GTK_WIDGET_CLASS (parent_class)->button_release_event (widget, event); +} + +static gboolean +gimp_spin_scale_motion_notify (GtkWidget *widget, + GdkEventMotion *event) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + + gdk_event_request_motions (event); + + gint x, y; + + gimp_spin_scale_event_to_widget_coords (widget, event->window, + event->x, event->y, + &x, &y); + + if (private->changing_value) + { + gimp_spin_scale_change_value (widget, x); + + return TRUE; + } + + GTK_WIDGET_CLASS (parent_class)->motion_notify_event (widget, event); + + if (! (event->state & + (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) + ) + { + GdkDisplay *display = gtk_widget_get_display (widget); + GdkCursor *cursor = NULL; + + switch (gimp_spin_scale_get_target (widget, x, y)) + { + case TARGET_NUMBER: + cursor = gdk_cursor_new_for_display (display, GDK_XTERM); + break; + + case TARGET_UPPER: + cursor = gdk_cursor_new_for_display (display, GDK_SB_UP_ARROW); + break; + + case TARGET_LOWER: + cursor = gdk_cursor_new_for_display (display, GDK_SB_H_DOUBLE_ARROW); + break; + + default: + break; + } + + if (cursor) + { + gdk_window_set_cursor (event->window, cursor); + g_object_unref (cursor); + } + } + + return FALSE; +} + +static gboolean +gimp_spin_scale_leave_notify (GtkWidget *widget, + GdkEventCrossing *event) +{ + gdk_window_set_cursor (event->window, NULL); + + return GTK_WIDGET_CLASS (parent_class)->leave_notify_event (widget, event); +} + +gboolean gimp_spin_scale_keypress( GtkWidget *widget, GdkEventKey *event) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + guint key = 0; + gdk_keymap_translate_keyboard_state( gdk_keymap_get_for_display( gdk_display_get_default() ), + event->hardware_keycode, (GdkModifierType)event->state, + 0, &key, 0, 0, 0 ); + + switch ( key ) { + + case GDK_KEY_Escape: + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + { + private->transferFocus = TRUE; + gimp_spin_scale_defocus( GTK_SPIN_BUTTON(widget) ); + } + break; + + } + + return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event); +} + +static void +gimp_spin_scale_defocus( GtkSpinButton *spin_button ) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (spin_button); + + if ( private->transferFocus ) { + if ( private->focusWidget ) { + gtk_widget_grab_focus( private->focusWidget ); + } + } +} + +static void +gimp_spin_scale_value_changed (GtkSpinButton *spin_button) +{ + GtkAdjustment *adjustment = gtk_spin_button_get_adjustment (spin_button); + GimpSpinScalePrivate *private = GET_PRIVATE (spin_button); + gdouble lower; + gdouble upper; + gdouble value; + + gimp_spin_scale_get_limits (GIMP_SPIN_SCALE (spin_button), &lower, &upper); + + value = CLAMP (gtk_adjustment_get_value (adjustment), lower, upper); + + gtk_entry_set_progress_fraction (GTK_ENTRY (spin_button), + pow ((value - lower) / (upper - lower), + 1.0 / private->gamma)); + + // TODO - Allow scrollwheel to change value then return focus, + // but clicks/keypress should keep focus in the control + //if ( gtk_widget_has_focus( GTK_WIDGET(spin_button) ) ) { + // gimp_spin_scale_defocus( spin_button ); + //} +} + + +/* public functions */ + +GtkWidget * +gimp_spin_scale_new (GtkAdjustment *adjustment, + const gchar *label, + gint digits) +{ + g_return_val_if_fail (GTK_IS_ADJUSTMENT (adjustment), NULL); + + return g_object_new (GIMP_TYPE_SPIN_SCALE, + "adjustment", adjustment, + "label", label, + "digits", digits, + NULL); +} + +void +gimp_spin_scale_set_label (GimpSpinScale *scale, + const gchar *label) +{ + GimpSpinScalePrivate *private; + + g_return_if_fail (GIMP_IS_SPIN_SCALE (scale)); + + private = GET_PRIVATE (scale); + + if (label == private->label) + return; + + g_free (private->label); + private->label = g_strdup (label); + + if (private->layout) + { + g_object_unref (private->layout); + private->layout = NULL; + } + + gtk_widget_queue_resize (GTK_WIDGET (scale)); + + g_object_notify (G_OBJECT (scale), "label"); +} + +const gchar * +gimp_spin_scale_get_label (GimpSpinScale *scale) +{ + g_return_val_if_fail (GIMP_IS_SPIN_SCALE (scale), NULL); + + return GET_PRIVATE (scale)->label; +} + +void +gimp_spin_scale_set_scale_limits (GimpSpinScale *scale, + gdouble lower, + gdouble upper) +{ + GimpSpinScalePrivate *private; + GtkSpinButton *spin_button; + GtkAdjustment *adjustment; + + g_return_if_fail (GIMP_IS_SPIN_SCALE (scale)); + + private = GET_PRIVATE (scale); + spin_button = GTK_SPIN_BUTTON (scale); + adjustment = gtk_spin_button_get_adjustment (spin_button); + + g_return_if_fail (lower >= gtk_adjustment_get_lower (adjustment)); + g_return_if_fail (upper <= gtk_adjustment_get_upper (adjustment)); + + private->scale_limits_set = TRUE; + private->scale_lower = lower; + private->scale_upper = upper; + private->gamma = 1.0; + + gimp_spin_scale_value_changed (spin_button); +} + +void +gimp_spin_scale_unset_scale_limits (GimpSpinScale *scale) +{ + GimpSpinScalePrivate *private; + + g_return_if_fail (GIMP_IS_SPIN_SCALE (scale)); + + private = GET_PRIVATE (scale); + + private->scale_limits_set = FALSE; + private->scale_lower = 0.0; + private->scale_upper = 0.0; + + gimp_spin_scale_value_changed (GTK_SPIN_BUTTON (scale)); +} + +gboolean +gimp_spin_scale_get_scale_limits (GimpSpinScale *scale, + gdouble *lower, + gdouble *upper) +{ + GimpSpinScalePrivate *private; + + g_return_val_if_fail (GIMP_IS_SPIN_SCALE (scale), FALSE); + + private = GET_PRIVATE (scale); + + if (lower) + *lower = private->scale_lower; + + if (upper) + *upper = private->scale_upper; + + return private->scale_limits_set; +} + +void +gimp_spin_scale_set_gamma (GimpSpinScale *scale, + gdouble gamma) +{ + GimpSpinScalePrivate *private; + + g_return_if_fail (GIMP_IS_SPIN_SCALE (scale)); + + private = GET_PRIVATE (scale); + + private->gamma = gamma; + + gimp_spin_scale_value_changed (GTK_SPIN_BUTTON (scale)); +} + +gdouble +gimp_spin_scale_get_gamma (GimpSpinScale *scale) +{ + g_return_val_if_fail (GIMP_IS_SPIN_SCALE (scale), 1.0); + + return GET_PRIVATE(scale)->gamma; +} diff --git a/src/widgets/gimp/gimpspinscale.h b/src/widgets/gimp/gimpspinscale.h new file mode 100644 index 000000000..b42a0faf8 --- /dev/null +++ b/src/widgets/gimp/gimpspinscale.h @@ -0,0 +1,82 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpspinscale.h + * Copyright (C) 2010 Michael Natterer <mitch@gimp.org> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_SPIN_SCALE_H__ +#define __GIMP_SPIN_SCALE_H__ + +#ifndef WITH_GIMP +#include <gtk/gtk.h> +#endif + +G_BEGIN_DECLS + +#define GIMP_TYPE_SPIN_SCALE (gimp_spin_scale_get_type ()) +#define GIMP_SPIN_SCALE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SPIN_SCALE, GimpSpinScale)) +#define GIMP_SPIN_SCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SPIN_SCALE, GimpSpinScaleClass)) +#define GIMP_IS_SPIN_SCALE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_SPIN_SCALE)) +#define GIMP_IS_SPIN_SCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SPIN_SCALE)) +#define GIMP_SPIN_SCALE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SPIN_SCALE, GimpSpinScaleClass)) + + +typedef struct _GimpSpinScale GimpSpinScale; +typedef struct _GimpSpinScaleClass GimpSpinScaleClass; + +struct _GimpSpinScale +{ + GtkSpinButton parent_instance; +}; + +struct _GimpSpinScaleClass +{ + GtkSpinButtonClass parent_class; +}; + + +GType gimp_spin_scale_get_type (void) G_GNUC_CONST; + +GtkWidget * gimp_spin_scale_new (GtkAdjustment *adjustment, + const gchar *label, + gint digits); + +void gimp_spin_scale_set_label (GimpSpinScale *scale, + const gchar *label); +const gchar * gimp_spin_scale_get_label (GimpSpinScale *scale); + +void gimp_spin_scale_set_scale_limits (GimpSpinScale *scale, + gdouble lower, + gdouble upper); +void gimp_spin_scale_unset_scale_limits (GimpSpinScale *scale); +gboolean gimp_spin_scale_get_scale_limits (GimpSpinScale *scale, + gdouble *lower, + gdouble *upper); + +void gimp_spin_scale_set_gamma (GimpSpinScale *scale, + gdouble gamma); +gdouble gimp_spin_scale_get_gamma (GimpSpinScale *scale); + +void gimp_spin_scale_set_focuswidget (GtkWidget *scale, + GtkWidget *widget); + +void gimp_spin_scale_set_appearance (GtkWidget *scale, + const gchar *appearance); + +G_END_DECLS + +#endif /* __GIMP_SPIN_SCALE_H__ */ diff --git a/src/widgets/ruler.cpp b/src/widgets/gimp/ruler.cpp index deffd384a..6a1f7f903 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/gimp/ruler.cpp @@ -12,7 +12,9 @@ * - We use a default font size of PANGO_SCALE_X_SMALL for labels, * GIMP uses PANGO_SCALE_SMALL (i.e., a bit larger than ours). * - * - We abbreviate large numbers in tick-labels (e.g., 10000 -> 10k) + * - We abbreviate large numbers in tick-labels (e.g., 10000 -> 10k) + * + * - GtkStateFlags are read from GtkStyleContext objects where appropriate * * Authors: * Lauris Kaplinski <lauris@kaplinski.com> @@ -31,13 +33,11 @@ #include <cmath> #include <cstdio> -#include "widget-sizes.h" #include "ruler.h" -#include "round.h" #include <glibmm/i18n.h> #include "util/units.h" -#define ROUND(x) ((int) ((x) + 0.5)) +#define ROUND(x) ((int) round(x)) #define GTK_PARAM_READWRITE G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB @@ -120,7 +120,6 @@ static void sp_ruler_unmap (GtkWidget *widget); static void sp_ruler_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -#if GTK_CHECK_VERSION(3,0,0) static void sp_ruler_get_preferred_width (GtkWidget *widget, gint *minimum_width, gint *natural_width); @@ -129,21 +128,11 @@ static void sp_ruler_get_preferred_height (GtkWidget *widget, gint *minimum_height, gint *natural_height); static void sp_ruler_style_updated (GtkWidget *widget); -#else -static void sp_ruler_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void sp_ruler_style_set (GtkWidget *widget, - GtkStyle *prev_style); -#endif static gboolean sp_ruler_motion_notify (GtkWidget *widget, GdkEventMotion *event); static gboolean sp_ruler_draw (GtkWidget *widget, cairo_t *cr); -#if !GTK_CHECK_VERSION(3,0,0) -static gboolean sp_ruler_expose (GtkWidget *widget, - GdkEventExpose *event); -#endif static void sp_ruler_draw_ticks (SPRuler *ruler); static GdkRectangle sp_ruler_get_pos_rect (SPRuler *ruler, gdouble position); @@ -181,16 +170,10 @@ sp_ruler_class_init (SPRulerClass *klass) widget_class->map = sp_ruler_map; widget_class->unmap = sp_ruler_unmap; widget_class->size_allocate = sp_ruler_size_allocate; -#if GTK_CHECK_VERSION(3,0,0) widget_class->get_preferred_width = sp_ruler_get_preferred_width; widget_class->get_preferred_height = sp_ruler_get_preferred_height; widget_class->style_updated = sp_ruler_style_updated; widget_class->draw = sp_ruler_draw; -#else - widget_class->size_request = sp_ruler_size_request; - widget_class->style_set = sp_ruler_style_set; - widget_class->expose_event = sp_ruler_expose; -#endif widget_class->motion_notify_event = sp_ruler_motion_notify; g_type_class_add_private (object_class, sizeof (SPRulerPrivate)); @@ -487,16 +470,10 @@ sp_ruler_realize (GtkWidget *widget) attributes.width = allocation.width; attributes.height = allocation.height; attributes.wclass = GDK_INPUT_ONLY; -#if GTK_CHECK_VERSION(3,0,0) attributes.event_mask = (gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); -#else - attributes.event_mask = (gtk_widget_get_events (widget) | - GDK_EXPOSURE_MASK | - GDK_POINTER_MOTION_MASK); -#endif attributes_mask = GDK_WA_X | GDK_WA_Y; @@ -572,7 +549,7 @@ sp_ruler_size_allocate (GtkWidget *widget, resized = (widget_allocation.width != allocation->width || widget_allocation.height != allocation->height); - gtk_widget_set_allocation(widget, allocation); + GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); if (gtk_widget_get_realized (widget)) { @@ -599,55 +576,34 @@ sp_ruler_size_request (GtkWidget *widget, size = 2 + ink_rect.height * 1.7; -#if GTK_CHECK_VERSION(3,0,0) GtkStyleContext *context = gtk_widget_get_style_context (widget); GtkBorder border; - gtk_style_context_get_border (context, static_cast<GtkStateFlags>(0), &border); + GtkStateFlags state_flags = gtk_style_context_get_state (context); + + gtk_style_context_get_border (context, state_flags, &border); requisition->width = border.left + border.right; requisition->height = border.top + border.bottom; -#else - GtkStyle *style = gtk_widget_get_style(widget); -#endif if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { -#if GTK_CHECK_VERSION(3,0,0) requisition->width += 1; requisition->height += size; -#else - requisition->width = style->xthickness * 2 + 1; - requisition->height = style->ythickness * 2 + size; -#endif } else { -#if GTK_CHECK_VERSION(3,0,0) requisition->width += size; requisition->height += 1; -#else - requisition->width = style->xthickness * 2 + size; - requisition->height = style->ythickness * 2 + 1; -#endif } } static void -#if GTK_CHECK_VERSION(3,0,0) sp_ruler_style_updated (GtkWidget *widget) -#else -sp_ruler_style_set (GtkWidget *widget, - GtkStyle *prev_style) -#endif { SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); -#if GTK_CHECK_VERSION(3,0,0) GTK_WIDGET_CLASS (sp_ruler_parent_class)->style_updated (widget); -#else - GTK_WIDGET_CLASS (sp_ruler_parent_class)->style_set (widget, prev_style); -#endif gtk_widget_style_get (widget, "font-scale", &priv->font_scale, @@ -660,7 +616,6 @@ sp_ruler_style_set (GtkWidget *widget, } } -#if GTK_CHECK_VERSION(3,0,0) static void sp_ruler_get_preferred_width (GtkWidget *widget, gint *minimum_width, @@ -684,33 +639,19 @@ sp_ruler_get_preferred_height (GtkWidget *widget, *minimum_height = *natural_height = requisition.height; } -#else -static gboolean -sp_ruler_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); - GtkAllocation allocation; - - gdk_cairo_region (cr, event->region); - cairo_clip (cr); - - gtk_widget_get_allocation (widget, &allocation); - - gboolean result = sp_ruler_draw (widget, cr); - - cairo_destroy (cr); - - return result; -} -#endif static gboolean sp_ruler_draw (GtkWidget *widget, cairo_t *cr) { - SPRuler *ruler = SP_RULER (widget); - SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + SPRuler *ruler = SP_RULER (widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkStyleContext *context = gtk_widget_get_style_context (widget); + GtkAllocation allocation; + + gtk_widget_get_allocation (widget, &allocation); + gtk_render_background (context, cr, 0, 0, allocation.width, allocation.height); + gtk_render_frame (context, cr, 0, 0, allocation.width, allocation.height); sp_ruler_draw_ticks (ruler); @@ -736,7 +677,7 @@ sp_ruler_make_pixmap (SPRuler *ruler) priv->backing_store = gdk_window_create_similar_surface (gtk_widget_get_window (widget), - CAIRO_CONTENT_COLOR, + CAIRO_CONTENT_COLOR_ALPHA, allocation.width, allocation.height); @@ -749,13 +690,8 @@ sp_ruler_draw_pos (SPRuler *ruler, { GtkWidget *widget = GTK_WIDGET (ruler); -#if GTK_CHECK_VERSION(3,0,0) GtkStyleContext *context = gtk_widget_get_style_context (widget); GdkRGBA color; -#else - GtkStyle *style = gtk_widget_get_style (widget); - GtkStateType state = gtk_widget_get_state (widget); -#endif SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); GdkRectangle pos_rect; @@ -767,13 +703,9 @@ sp_ruler_draw_pos (SPRuler *ruler, if ((pos_rect.width > 0) && (pos_rect.height > 0)) { -#if GTK_CHECK_VERSION(3,0,0) gtk_style_context_get_color (context, gtk_widget_get_state_flags (widget), &color); gdk_cairo_set_source_rgba (cr, &color); -#else - gdk_cairo_set_source_color (cr, &style->fg[state]); -#endif cairo_move_to (cr, pos_rect.x, pos_rect.y); @@ -796,7 +728,17 @@ sp_ruler_draw_pos (SPRuler *ruler, cairo_fill (cr); } - priv->last_pos_rect = pos_rect; + if (priv->last_pos_rect.width != 0 && + priv->last_pos_rect.height != 0) + { + gdk_rectangle_union (&priv->last_pos_rect, + &pos_rect, + &priv->last_pos_rect); + } + else + { + priv->last_pos_rect = pos_rect; + } } /** @@ -1070,6 +1012,12 @@ sp_ruler_set_position (SPRuler *ruler, (ABS (xdiff) > IMMEDIATE_REDRAW_THRESHOLD || ABS (ydiff) > IMMEDIATE_REDRAW_THRESHOLD)) { + if (priv->pos_redraw_idle_id) + { + g_source_remove (priv->pos_redraw_idle_id); + priv->pos_redraw_idle_id = 0; + } + sp_ruler_queue_pos_redraw (ruler); } else if (! priv->pos_redraw_idle_id) @@ -1112,16 +1060,9 @@ sp_ruler_draw_ticks (SPRuler *ruler) { GtkWidget *widget = GTK_WIDGET (ruler); -#if GTK_CHECK_VERSION(3,0,0) GtkStyleContext *context = gtk_widget_get_style_context (widget); GtkBorder border; GdkRGBA color; -#else - GtkStyle *style = gtk_widget_get_style (widget); - GtkStateType state = gtk_widget_get_state (widget); - gint xthickness; - gint ythickness; -#endif SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); GtkAllocation allocation; @@ -1150,12 +1091,9 @@ sp_ruler_draw_ticks (SPRuler *ruler) gtk_widget_get_allocation (widget, &allocation); -#if GTK_CHECK_VERSION(3,0,0) - gtk_style_context_get_border (context, static_cast<GtkStateFlags>(0), &border); -#else - xthickness = style->xthickness; - ythickness = style->ythickness; -#endif + GtkStateFlags state_flags = gtk_style_context_get_state (context); + + gtk_style_context_get_border (context, state_flags, &border); layout = sp_ruler_get_layout (widget, "0123456789"); pango_layout_get_extents (layout, &ink_rect, &logical_rect); @@ -1166,28 +1104,20 @@ sp_ruler_draw_ticks (SPRuler *ruler) if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { width = allocation.width; -#if GTK_CHECK_VERSION(3,0,0) height = allocation.height - (border.top + border.bottom); -#else - height = allocation.height - ythickness * 2; -#endif } else { width = allocation.height; -#if GTK_CHECK_VERSION(3,0,0) height = allocation.width - (border.top + border.bottom); -#else - height = allocation.width - ythickness * 2; -#endif } cr = cairo_create (priv->backing_store); -#if GTK_CHECK_VERSION(3,0,0) - gtk_render_background (context, cr, 0, 0, allocation.width, allocation.height); - gtk_render_frame (context, cr, 0, 0, allocation.width, allocation.height); - + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (cr); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + gtk_style_context_get_color (context, gtk_widget_get_state_flags (widget), &color); gdk_cairo_set_source_rgba (cr, &color); @@ -1208,30 +1138,6 @@ sp_ruler_draw_ticks (SPRuler *ruler) 1, allocation.height - (border.top + border.bottom)); } -#else - gdk_cairo_set_source_color (cr, &style->bg[state]); - - cairo_paint (cr); - - gdk_cairo_set_source_color(cr, &style->fg[state]); - - if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) - { - cairo_rectangle (cr, - xthickness, - height + ythickness, - allocation.width - 2 * xthickness, - 1); - } - else - { - cairo_rectangle (cr, - height + xthickness, - ythickness, - 1, - allocation.height - 2 * ythickness); - } -#endif sp_ruler_get_range (ruler, &lower, &upper, &max_size); @@ -1310,9 +1216,8 @@ sp_ruler_draw_ticks (SPRuler *ruler) // be e.g. 641.50000000000; rounding behaviour is not defined in such a case (see round.h) // and jitter will be apparent (upon redrawing some of the lines on the ruler might jump a // by a pixel, and jump back on the next redraw). This is suppressed by adding 1e-9 (that's only one nanopixel ;-)) - pos = gint(Inkscape::round((cur - lower) * increment + 1e-12)); + pos = gint(round((cur - lower) * increment + 1e-12)); -#if GTK_CHECK_VERSION(3,0,0) if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { cairo_rectangle (cr, @@ -1325,20 +1230,6 @@ sp_ruler_draw_ticks (SPRuler *ruler) height + border.left - length, pos, length, 1); } -#else - if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) - { - cairo_rectangle (cr, - pos, height + ythickness - length, - 1, length); - } - else - { - cairo_rectangle (cr, - height + xthickness - length, pos, - length, 1); - } -#endif /* draw label */ double label_spacing_px = fabs(increment*(double)ruler_metric.ruler_scale[scale]/ruler_metric.subdivide[i]); @@ -1356,15 +1247,9 @@ sp_ruler_draw_ticks (SPRuler *ruler) pango_layout_set_text (layout, unit_str, -1); pango_layout_get_extents (layout, &logical_rect, NULL); -#if GTK_CHECK_VERSION(3,0,0) cairo_move_to (cr, pos + 2, border.top + PANGO_PIXELS (logical_rect.y - digit_offset)); -#else - cairo_move_to (cr, - pos + 2, - ythickness + PANGO_PIXELS (logical_rect.y - digit_offset)); -#endif pango_cairo_show_layout(cr, layout); } @@ -1378,15 +1263,9 @@ sp_ruler_draw_ticks (SPRuler *ruler) pango_layout_set_text (layout, digit_str, 1); pango_layout_get_extents (layout, NULL, &logical_rect); -#if GTK_CHECK_VERSION(3,0,0) cairo_move_to (cr, border.left + 1, pos + digit_height * j + 2 + PANGO_PIXELS (logical_rect.y - digit_offset)); -#else - cairo_move_to (cr, - xthickness + 1, - pos + digit_height * j + 2 + PANGO_PIXELS (logical_rect.y - digit_offset)); -#endif pango_cairo_show_layout (cr, layout); } } @@ -1423,19 +1302,15 @@ sp_ruler_get_pos_rect (SPRuler *ruler, gtk_widget_get_allocation (widget, &allocation); -#if GTK_CHECK_VERSION(3,0,0) GtkStyleContext *context = gtk_widget_get_style_context (widget); GtkBorder padding; - gtk_style_context_get_border(context, static_cast<GtkStateFlags>(0), &padding); + GtkStateFlags state_flags = gtk_style_context_get_state (context); + + gtk_style_context_get_border(context, state_flags, &padding); xthickness = padding.left + padding.right; ythickness = padding.top + padding.bottom; -#else - GtkStyle *style = gtk_widget_get_style (widget); - xthickness = style->xthickness; - ythickness = style->ythickness; -#endif if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { @@ -1473,9 +1348,6 @@ sp_ruler_get_pos_rect (SPRuler *ruler, rect.y = ROUND ((position - lower) * increment) + (ythickness - rect.height) / 2 - 1; } - rect.x += allocation.x; - rect.y += allocation.y; - return rect; } @@ -1498,18 +1370,22 @@ sp_ruler_queue_pos_redraw (SPRuler *ruler) { SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); const GdkRectangle rect = sp_ruler_get_pos_rect (ruler, priv->position); + GtkAllocation allocation; + + gtk_widget_get_allocation (GTK_WIDGET(ruler), &allocation); - gtk_widget_queue_draw_area (GTK_WIDGET(ruler), - rect.x, - rect.y, + gtk_widget_queue_draw_area (GTK_WIDGET (ruler), + rect.x + allocation.x, + rect.y + allocation.y, rect.width, rect.height); - if (priv->last_pos_rect.width != 0 || priv->last_pos_rect.height != 0) + if (priv->last_pos_rect.width != 0 && + priv->last_pos_rect.height != 0) { - gtk_widget_queue_draw_area (GTK_WIDGET(ruler), - priv->last_pos_rect.x, - priv->last_pos_rect.y, + gtk_widget_queue_draw_area (GTK_WIDGET (ruler), + priv->last_pos_rect.x + allocation.x, + priv->last_pos_rect.y + allocation.y, priv->last_pos_rect.width, priv->last_pos_rect.height); diff --git a/src/widgets/ruler.h b/src/widgets/gimp/ruler.h index ed529d082..ed529d082 100644 --- a/src/widgets/ruler.h +++ b/src/widgets/gimp/ruler.h diff --git a/src/widgets/gradient-image.cpp b/src/widgets/gradient-image.cpp index 6901b8549..dff564feb 100644 --- a/src/widgets/gradient-image.cpp +++ b/src/widgets/gradient-image.cpp @@ -21,7 +21,6 @@ static void sp_gradient_image_size_request (GtkWidget *widget, GtkRequisition *requisition); -#if GTK_CHECK_VERSION(3,0,0) static void sp_gradient_image_destroy(GtkWidget *object); static void sp_gradient_image_get_preferred_width(GtkWidget *widget, gint *minimal_width, @@ -30,11 +29,6 @@ static void sp_gradient_image_get_preferred_width(GtkWidget *widget, static void sp_gradient_image_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height); -#else -static void sp_gradient_image_destroy(GtkObject *object); -static gboolean sp_gradient_image_expose(GtkWidget *widget, GdkEventExpose *event); -#endif - static gboolean sp_gradient_image_draw(GtkWidget *widget, cairo_t *cr); static void sp_gradient_image_gradient_release (SPObject *, SPGradientImage *im); static void sp_gradient_image_gradient_modified (SPObject *, guint flags, SPGradientImage *im); @@ -46,18 +40,10 @@ static void sp_gradient_image_class_init(SPGradientImageClass *klass) { GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); -#if GTK_CHECK_VERSION(3,0,0) widget_class->get_preferred_width = sp_gradient_image_get_preferred_width; widget_class->get_preferred_height = sp_gradient_image_get_preferred_height; widget_class->draw = sp_gradient_image_draw; widget_class->destroy = sp_gradient_image_destroy; -#else - GtkObjectClass *object_class = GTK_OBJECT_CLASS(klass); - - object_class->destroy = sp_gradient_image_destroy; - widget_class->size_request = sp_gradient_image_size_request; - widget_class->expose_event = sp_gradient_image_expose; -#endif } static void @@ -71,11 +57,7 @@ sp_gradient_image_init (SPGradientImage *image) new (&image->modified_connection) sigc::connection(); } -#if GTK_CHECK_VERSION(3,0,0) static void sp_gradient_image_destroy(GtkWidget *object) -#else -static void sp_gradient_image_destroy(GtkObject *object) -#endif { SPGradientImage *image = SP_GRADIENT_IMAGE (object); @@ -88,13 +70,8 @@ static void sp_gradient_image_destroy(GtkObject *object) image->release_connection.~connection(); image->modified_connection.~connection(); -#if GTK_CHECK_VERSION(3,0,0) if (GTK_WIDGET_CLASS(sp_gradient_image_parent_class)->destroy) GTK_WIDGET_CLASS(sp_gradient_image_parent_class)->destroy(object); -#else - if (GTK_OBJECT_CLASS(sp_gradient_image_parent_class)->destroy) - GTK_OBJECT_CLASS(sp_gradient_image_parent_class)->destroy(object); -#endif } static void sp_gradient_image_size_request(GtkWidget * /*widget*/, GtkRequisition *requisition) @@ -103,7 +80,6 @@ static void sp_gradient_image_size_request(GtkWidget * /*widget*/, GtkRequisitio requisition->height = 12; } -#if GTK_CHECK_VERSION(3,0,0) static void sp_gradient_image_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width) { GtkRequisition requisition; @@ -117,27 +93,6 @@ static void sp_gradient_image_get_preferred_height(GtkWidget *widget, gint *mini sp_gradient_image_size_request(widget, &requisition); *minimal_height = *natural_height = requisition.height; } -#endif - -#if !GTK_CHECK_VERSION(3,0,0) -static gboolean sp_gradient_image_expose(GtkWidget *widget, GdkEventExpose *event) -{ - gboolean result = TRUE; - if(gtk_widget_is_drawable(widget)) { - cairo_t *ct = gdk_cairo_create(gtk_widget_get_window (widget)); - cairo_rectangle(ct, event->area.x, event->area.y, - event->area.width, event->area.height); - cairo_clip(ct); - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - cairo_translate(ct, allocation.x, allocation.y); - result = sp_gradient_image_draw(widget, ct); - cairo_destroy(ct); - } - - return result; -} -#endif static gboolean sp_gradient_image_draw(GtkWidget *widget, cairo_t *ct) { diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index 604ecd108..569f66c2b 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -14,7 +14,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <gtkmm/treeview.h> @@ -28,14 +28,11 @@ #include "inkscape.h" #include "verbs.h" #include "helper/action.h" -#include "helper/action-context.h" #include "preferences.h" #include "widgets/icon.h" #include <glibmm/i18n.h> -#include <xml/repr.h> -#include "gradient-selector.h" #include "paint-selector.h" #include "style.h" #include "id-clash.h" @@ -60,11 +57,7 @@ static void sp_gradient_selector_delete_vector_clicked (GtkWidget *w, SPGradient static guint signals[LAST_SIGNAL] = {0}; -#if GTK_CHECK_VERSION(3,0,0) G_DEFINE_TYPE(SPGradientSelector, sp_gradient_selector, GTK_TYPE_BOX); -#else -G_DEFINE_TYPE(SPGradientSelector, sp_gradient_selector, GTK_TYPE_VBOX); -#endif static void sp_gradient_selector_class_init(SPGradientSelectorClass *klass) { @@ -116,9 +109,7 @@ static void sp_gradient_selector_init(SPGradientSelector *sel) sel->safelyInit = true; sel->blocked = false; -#if GTK_CHECK_VERSION(3,0,0) gtk_orientable_set_orientation(GTK_ORIENTABLE(sel), GTK_ORIENTATION_VERTICAL); -#endif new (&sel->nonsolid) std::vector<GtkWidget*>(); new (&sel->swatch_widgets) std::vector<GtkWidget*>(); @@ -180,13 +171,8 @@ static void sp_gradient_selector_init(SPGradientSelector *sel) /* Create box for buttons */ -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + auto hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); -#else - GtkWidget *hb = gtk_hbox_new( FALSE, 2 ); -#endif - //sel->nonsolid.push_back(hb); gtk_box_pack_start( GTK_BOX(sel), hb, FALSE, FALSE, 0 ); sel->add = gtk_button_new(); diff --git a/src/widgets/gradient-selector.h b/src/widgets/gradient-selector.h index e090d7cbd..e058c5112 100644 --- a/src/widgets/gradient-selector.h +++ b/src/widgets/gradient-selector.h @@ -45,18 +45,11 @@ class TreeView; struct SPGradientSelector { -#if GTK_CHECK_VERSION(3,0,0) GtkBox vbox; -#else - GtkVBox vbox; -#endif enum SelectorMode { MODE_LINEAR, MODE_RADIAL, -#ifdef WITH_MESH - MODE_MESH, -#endif MODE_SWATCH }; @@ -131,11 +124,7 @@ struct SPGradientSelector { }; struct SPGradientSelectorClass { -#if GTK_CHECK_VERSION(3,0,0) GtkBoxClass parent_class; -#else - GtkVBoxClass parent_class; -#endif void (* grabbed) (SPGradientSelector *sel); void (* dragged) (SPGradientSelector *sel); diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp index a44e9962e..8474327ca 100644 --- a/src/widgets/gradient-toolbar.cpp +++ b/src/widgets/gradient-toolbar.cpp @@ -13,7 +13,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include "ui/widget/color-preview.h" @@ -27,9 +27,10 @@ #include "gradient-chemistry.h" #include "gradient-drag.h" #include "gradient-toolbar.h" -#include "widgets/ink-action.h" +#include "ink-action.h" +#include "ink-radio-action.h" +#include "ink-toggle-action.h" #include "macros.h" -#include "preferences.h" #include "selection.h" #include "sp-defs.h" #include "sp-linear-gradient.h" @@ -116,8 +117,8 @@ void gr_apply_gradient(Inkscape::Selection *selection, GrDrag *drag, SPGradient } // If no drag or no dragger selected, act on selection - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ gr_apply_gradient_to_item(*i, gr, initialType, initialMode, initialMode); } } @@ -216,8 +217,8 @@ void gr_get_dt_selected_gradient(Inkscape::Selection *selection, SPGradient *&gr { SPGradient *gradient = 0; - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i;// get the items gradient, not the getVector() version SPStyle *style = item->style; SPPaintServer *server = 0; @@ -284,8 +285,8 @@ void gr_read_selection( Inkscape::Selection *selection, } // If no selected dragger, read desktop selection - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; SPStyle *style = item->style; @@ -720,9 +721,9 @@ static void select_stop_by_drag(GtkWidget *combo_box, SPGradient *gradient, Tool static void select_stop_in_list( GtkWidget *combo_box, SPGradient *gradient, SPStop *new_stop, GtkWidget *data, gboolean block) { int i = 0; - for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (SP_IS_STOP(ochild)) { - if (ochild == new_stop) { + for (auto& ochild: gradient->children) { + if (SP_IS_STOP(&ochild)) { + if (&ochild == new_stop) { blocked = block; gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box) , i); gr_stop_set_offset(GTK_COMBO_BOX(combo_box), data); @@ -765,9 +766,9 @@ static gboolean update_stop_list( GtkWidget *stop_combo, SPGradient *gradient, S /* Populate the combobox store */ std::vector<SPObject *> sl; if ( gradient->hasStops() ) { - for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (SP_IS_STOP(ochild)) { - sl.push_back(ochild); + for (auto& ochild: gradient->children) { + if (SP_IS_STOP(&ochild)) { + sl.push_back(&ochild); } } } diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index 97e65141f..0c5f3cf47 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -20,14 +20,13 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <glibmm.h> #include "gradient-vector.h" #include "ui/widget/color-preview.h" #include "verbs.h" -#include <gtk/gtk.h> #include "macros.h" #include <glibmm/i18n.h> #include <set> @@ -50,8 +49,6 @@ #include "desktop.h" #include "layer-manager.h" -#include <sigc++/functors/ptr_fun.h> -#include <sigc++/adaptors/bind.h> #include "document-undo.h" #include "ui/dialog-events.h" @@ -66,11 +63,7 @@ enum { LAST_SIGNAL }; -#if GTK_CHECK_VERSION(3,0,0) static void sp_gradient_vector_selector_destroy(GtkWidget *object); -#else -static void sp_gradient_vector_selector_destroy(GtkObject *object); -#endif static void sp_gvs_gradient_release(SPObject *obj, SPGradientVectorSelector *gvs); static void sp_gvs_defs_release(SPObject *defs, SPGradientVectorSelector *gvs); @@ -89,11 +82,7 @@ static win_data wd; static gint x = -1000, y = -1000, w = 0, h = 0; // impossible original values to make sure they are read from prefs static Glib::ustring const prefs_path = "/dialogs/gradienteditor/"; -#if GTK_CHECK_VERSION(3,0,0) G_DEFINE_TYPE(SPGradientVectorSelector, sp_gradient_vector_selector, GTK_TYPE_BOX); -#else -G_DEFINE_TYPE(SPGradientVectorSelector, sp_gradient_vector_selector, GTK_TYPE_VBOX); -#endif static void sp_gradient_vector_selector_class_init(SPGradientVectorSelectorClass *klass) { @@ -108,20 +97,13 @@ static void sp_gradient_vector_selector_class_init(SPGradientVectorSelectorClass G_TYPE_NONE, 1, G_TYPE_POINTER); -#if GTK_CHECK_VERSION(3,0,0) GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); widget_class->destroy = sp_gradient_vector_selector_destroy; -#else - GtkObjectClass *object_class = GTK_OBJECT_CLASS(klass); - object_class->destroy = sp_gradient_vector_selector_destroy; -#endif } static void sp_gradient_vector_selector_init(SPGradientVectorSelector *gvs) { -#if GTK_CHECK_VERSION(3,0,0) gtk_orientable_set_orientation(GTK_ORIENTABLE(gvs), GTK_ORIENTATION_VERTICAL); -#endif gvs->idlabel = TRUE; @@ -140,11 +122,7 @@ static void sp_gradient_vector_selector_init(SPGradientVectorSelector *gvs) } -#if GTK_CHECK_VERSION(3,0,0) static void sp_gradient_vector_selector_destroy(GtkWidget *object) -#else -static void sp_gradient_vector_selector_destroy(GtkObject *object) -#endif { SPGradientVectorSelector *gvs = SP_GRADIENT_VECTOR_SELECTOR(object); @@ -165,15 +143,9 @@ static void sp_gradient_vector_selector_destroy(GtkObject *object) gvs->defs_modified_connection.~connection(); gvs->tree_select_connection.~connection(); -#if GTK_CHECK_VERSION(3,0,0) if ((GTK_WIDGET_CLASS(sp_gradient_vector_selector_parent_class))->destroy) { (GTK_WIDGET_CLASS(sp_gradient_vector_selector_parent_class))->destroy(object); } -#else - if ((GTK_OBJECT_CLASS(sp_gradient_vector_selector_parent_class))->destroy) { - (GTK_OBJECT_CLASS(sp_gradient_vector_selector_parent_class))->destroy(object); - } -#endif } GtkWidget *sp_gradient_vector_selector_new(SPDocument *doc, SPGradient *gr) @@ -363,13 +335,13 @@ unsigned long sp_gradient_to_hhssll(SPGradient *gr) static GSList *get_all_doc_items(GSList *list, SPObject *from, bool onlyvisible, bool onlysensitive, bool ingroups, GSList const *exclude) { - for ( SPObject *child = from->firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - list = g_slist_prepend(list, SP_ITEM(child)); + for (auto& child: from->children) { + if (SP_IS_ITEM(&child)) { + list = g_slist_prepend(list, SP_ITEM(&child)); } - if (ingroups || SP_IS_ITEM(child)) { - list = get_all_doc_items(list, child, onlyvisible, onlysensitive, ingroups, exclude); + if (ingroups || SP_IS_ITEM(&child)) { + list = get_all_doc_items(list, &child, onlyvisible, onlysensitive, ingroups, exclude); } } @@ -476,7 +448,6 @@ void SPGradientVectorSelector::setSwatched() #include "widgets/widget-sizes.h" #include "xml/node-event-vector.h" #include "svg/svg-color.h" -#include "ui/widget/color-notebook.h" #define PAD 4 @@ -484,15 +455,8 @@ static GtkWidget *sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *st static void sp_gradient_vector_widget_load_gradient(GtkWidget *widget, SPGradient *gradient); static gint sp_gradient_vector_dialog_delete(GtkWidget *widget, GdkEvent *event, GtkWidget *dialog); - -#if GTK_CHECK_VERSION(3,0,0) static void sp_gradient_vector_dialog_destroy(GtkWidget *object, gpointer data); static void sp_gradient_vector_widget_destroy(GtkWidget *object, gpointer data); -#else -static void sp_gradient_vector_dialog_destroy(GtkObject *object, gpointer data); -static void sp_gradient_vector_widget_destroy(GtkObject *object, gpointer data); -#endif - static void sp_gradient_vector_gradient_release(SPObject *obj, GtkWidget *widget); static void sp_gradient_vector_gradient_modified(SPObject *obj, guint flags, GtkWidget *widget); static void sp_gradient_vector_color_dragged(Inkscape::UI::SelectedColor *selected_color, GObject *object); @@ -525,10 +489,10 @@ static void verify_grad(SPGradient *gradient) int i = 0; SPStop *stop = NULL; /* count stops */ - for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (SP_IS_STOP(ochild)) { + for (auto& ochild: gradient->children) { + if (SP_IS_STOP(&ochild)) { i++; - stop = SP_STOP(ochild); + stop = SP_STOP(&ochild); } } @@ -568,9 +532,9 @@ static void select_stop_in_list( GtkWidget *vb, SPGradient *gradient, SPStop *ne GtkWidget *combo_box = static_cast<GtkWidget *>(g_object_get_data(G_OBJECT(vb), "combo_box")); int i = 0; - for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (SP_IS_STOP(ochild)) { - if (ochild == new_stop) { + for (auto& ochild: gradient->children) { + if (SP_IS_STOP(&ochild)) { + if (&ochild == new_stop) { gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box) , i); break; } @@ -603,9 +567,9 @@ static void update_stop_list( GtkWidget *vb, SPGradient *gradient, SPStop *new_s /* Populate the combobox store */ GSList *sl = NULL; if ( gradient->hasStops() ) { - for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (SP_IS_STOP(ochild)) { - sl = g_slist_append(sl, ochild); + for (auto& ochild: gradient->children) { + if (SP_IS_STOP(&ochild)) { + sl = g_slist_append(sl, &ochild); } } } @@ -845,12 +809,8 @@ static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *s g_return_val_if_fail(gradient != NULL, NULL); g_return_val_if_fail(SP_IS_GRADIENT(gradient), NULL); -#if GTK_CHECK_VERSION(3,0,0) vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, PAD); gtk_box_set_homogeneous(GTK_BOX(vb), FALSE); -#else - vb = gtk_vbox_new(FALSE, PAD); -#endif g_signal_connect(G_OBJECT(vb), "destroy", G_CALLBACK(sp_gradient_vector_widget_destroy), NULL); w = sp_gradient_image_new(gradient); @@ -883,12 +843,8 @@ static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *s g_signal_connect(G_OBJECT(combo_box), "changed", G_CALLBACK(sp_grad_edit_combo_box_changed), vb); /* Add and Remove buttons */ -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1); + auto hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1); gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); -#else - GtkWidget *hb = gtk_hbox_new(FALSE, 1); -#endif // TRANSLATORS: "Stop" means: a "phase" of a gradient GtkWidget *b = gtk_button_new_with_label(_("Add stop")); gtk_widget_show(b); @@ -905,21 +861,12 @@ static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *s gtk_box_pack_start(GTK_BOX(vb),hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS); /* Offset Slider and stuff */ -#if GTK_CHECK_VERSION(3,0,0) hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); -#else - hb = gtk_hbox_new(FALSE, 0); -#endif /* Label */ GtkWidget *l = gtk_label_new(C_("Gradient","Offset:")); - -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_halign(l, GTK_ALIGN_END); -#else - gtk_misc_set_alignment(GTK_MISC(l), 1.0, 0.5); -#endif gtk_box_pack_start(GTK_BOX(hb),l, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS); gtk_widget_show(l); @@ -937,11 +884,7 @@ static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *s gtk_adjustment_set_value(Offset_adj, stop->offset); /* Slider */ -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *slider = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, Offset_adj); -#else - GtkWidget *slider = gtk_hscale_new(Offset_adj); -#endif + auto slider = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, Offset_adj); gtk_scale_set_draw_value( GTK_SCALE(slider), FALSE ); gtk_widget_show(slider); gtk_box_pack_start(GTK_BOX(hb),slider, TRUE, TRUE, AUX_BETWEEN_BUTTON_GROUPS); @@ -1179,11 +1122,7 @@ static void sp_gradient_vector_widget_load_gradient(GtkWidget *widget, SPGradien blocked = FALSE; } -#if GTK_CHECK_VERSION(3,0,0) static void sp_gradient_vector_dialog_destroy(GtkWidget * /*object*/, gpointer /*data*/) -#else -static void sp_gradient_vector_dialog_destroy(GtkObject * /*object*/, gpointer /*data*/) -#endif { GObject *obj = G_OBJECT(dlg); assert(obj != NULL); @@ -1234,11 +1173,7 @@ static gboolean sp_gradient_vector_dialog_delete(GtkWidget */*widget*/, GdkEvent } /* Widget destroy handler */ -#if GTK_CHECK_VERSION(3,0,0) static void sp_gradient_vector_widget_destroy(GtkWidget *object, gpointer /*data*/) -#else -static void sp_gradient_vector_widget_destroy(GtkObject *object, gpointer /*data*/) -#endif { SPObject *gradient = SP_OBJECT(g_object_get_data(G_OBJECT(object), "gradient")); diff --git a/src/widgets/gradient-vector.h b/src/widgets/gradient-vector.h index 5ae90b28f..b51b276b9 100644 --- a/src/widgets/gradient-vector.h +++ b/src/widgets/gradient-vector.h @@ -35,11 +35,7 @@ class SPGradient; class SPStop; struct SPGradientVectorSelector { -#if GTK_CHECK_VERSION(3,0,0) GtkBox vbox; -#else - GtkVBox vbox; -#endif guint idlabel : 1; @@ -61,11 +57,7 @@ struct SPGradientVectorSelector { }; struct SPGradientVectorSelectorClass { -#if GTK_CHECK_VERSION(3,0,0) GtkBoxClass parent_class; -#else - GtkVBoxClass parent_class; -#endif void (* vector_set) (SPGradientVectorSelector *gvs, SPGradient *gr); }; diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index f2031fe51..885deaab7 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -16,28 +16,26 @@ # include "config.h" #endif +#include <glibmm/fileutils.h> +#include <glibmm/miscutils.h> #include <gtkmm/icontheme.h> #include <cstring> -#include <glib.h> #include <glib/gstdio.h> #include <gtk/gtk.h> #include <gtkmm/image.h> -#include <gdkmm/pixbuf.h> -#include <glibmm/fileutils.h> -#include <glibmm/miscutils.h> #include <2geom/transforms.h> #include "path-prefix.h" #include "preferences.h" #include "inkscape.h" #include "document.h" -#include "sp-item.h" #include "display/cairo-utils.h" #include "display/drawing-context.h" #include "display/drawing-item.h" #include "display/drawing.h" #include "io/sys.h" #include "sp-root.h" +#include "sp-namedview.h" #include "util/units.h" #include "icon.h" @@ -64,10 +62,6 @@ struct IconImpl { static void sizeAllocate(GtkWidget *widget, GtkAllocation *allocation); static gboolean draw(GtkWidget *widget, cairo_t *cr); -#if !GTK_CHECK_VERSION(3,0,0) - static gboolean expose(GtkWidget *widget, GdkEventExpose *event); -#endif - static void screenChanged( GtkWidget *widget, GdkScreen *previous_screen ); static void styleSet( GtkWidget *widget, GtkStyle *previous_style ); static void themeChanged( SPIcon *icon ); @@ -149,14 +143,9 @@ sp_icon_class_init(SPIconClass *klass) object_class->dispose = IconImpl::dispose; -#if GTK_CHECK_VERSION(3,0,0) widget_class->get_preferred_width = IconImpl::getPreferredWidth; widget_class->get_preferred_height = IconImpl::getPreferredHeight; widget_class->draw = IconImpl::draw; -#else - widget_class->size_request = IconImpl::sizeRequest; - widget_class->expose_event = IconImpl::expose; -#endif widget_class->size_allocate = IconImpl::sizeAllocate; widget_class->screen_changed = IconImpl::screenChanged; widget_class->style_set = IconImpl::styleSet; @@ -244,37 +233,15 @@ gboolean IconImpl::draw(GtkWidget *widget, cairo_t* cr) bool unref_image = false; /* copied from the expose function of GtkImage */ -#if GTK_CHECK_VERSION(3,0,0) if (gtk_widget_get_state_flags (GTK_WIDGET(icon)) != GTK_STATE_FLAG_NORMAL && image) { -#else - if (gtk_widget_get_state (GTK_WIDGET(icon)) != GTK_STATE_NORMAL && image) { - std::cerr << "IconImpl::draw: Ooops! It is called in GTK2" << std::endl; -#endif std::cerr << "IconImpl::draw: No image, creating fallback" << std::endl; -#if GTK_CHECK_VERSION(3,0,0) - // image = gtk_render_icon_pixbuf(gtk_widget_get_style_context(widget), - // source, - // (GtkIconSize)-1); - - // gtk_render_icon_pixbuf deprecated, replaced by: GtkIconTheme *icon_theme = gtk_icon_theme_get_default(); image = gtk_icon_theme_load_icon (icon_theme, "gtk-image", 32, (GtkIconLookupFlags)0, NULL); -#else - GtkIconSource *source = gtk_icon_source_new(); - gtk_icon_source_set_pixbuf(source, icon->pb); - gtk_icon_source_set_size(source, GTK_ICON_SIZE_SMALL_TOOLBAR); // note: this is boilerplate and not used - gtk_icon_source_set_size_wildcarded(source, FALSE); - image = gtk_style_render_icon(gtk_widget_get_style(widget), source, - gtk_widget_get_direction(widget), - (GtkStateType) gtk_widget_get_state(widget), - (GtkIconSize)-1, widget, "gtk-image"); - gtk_icon_source_free(source); -#endif unref_image = true; } @@ -283,12 +250,7 @@ gboolean IconImpl::draw(GtkWidget *widget, cairo_t* cr) GtkAllocation allocation; GtkRequisition requisition; gtk_widget_get_allocation(widget, &allocation); - -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_get_preferred_size(widget, &requisition, NULL); -#else - gtk_widget_get_requisition(widget, &requisition); -#endif int x = floor(allocation.x + ((allocation.width - requisition.width) * 0.5)); int y = floor(allocation.y + ((allocation.height - requisition.height) * 0.5)); @@ -308,21 +270,6 @@ gboolean IconImpl::draw(GtkWidget *widget, cairo_t* cr) return TRUE; } -#if !GTK_CHECK_VERSION(3,0,0) -gboolean IconImpl::expose(GtkWidget *widget, GdkEventExpose * /*event*/) -{ - gboolean result = TRUE; - - if (gtk_widget_is_drawable(widget)) { - cairo_t * cr = gdk_cairo_create(gtk_widget_get_window(widget)); - result = draw(widget, cr); - cairo_destroy(cr); - } - - return result; -} -#endif - // PUBLIC CALL: void sp_icon_fetch_pixbuf( SPIcon *icon ) { @@ -1217,6 +1164,19 @@ sp_icon_doc_icon( SPDocument *doc, Inkscape::Drawing &drawing, CAIRO_FORMAT_ARGB32, psize, psize, stride); Inkscape::DrawingContext dc(s, ua.min()); + SPNamedView *nv = sp_document_namedview(doc, NULL); + float bg_r = SP_RGBA32_R_F(nv->pagecolor); + float bg_g = SP_RGBA32_G_F(nv->pagecolor); + float bg_b = SP_RGBA32_B_F(nv->pagecolor); + float bg_a = SP_RGBA32_A_F(nv->pagecolor); + + cairo_t *cr = cairo_create(s); + cairo_set_source_rgba(cr, bg_r, bg_g, bg_b, bg_a); + cairo_rectangle(cr, 0, 0, psize, psize); + cairo_fill(cr); + cairo_save(cr); + cairo_destroy(cr); + drawing.render(dc, ua); cairo_surface_destroy(s); diff --git a/src/widgets/image-menu-item.c b/src/widgets/image-menu-item.c deleted file mode 100644 index 2b9500ba0..000000000 --- a/src/widgets/image-menu-item.c +++ /dev/null @@ -1,1071 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 2001 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. - * Forked by . Icons in menus are important to us. - */ - -#include "config.h" - -#include <glib/gi18n-lib.h> -#include <gtk/gtk.h> - -#include "widgets/image-menu-item.h" - -/** - * SECTION:gtkimagemenuitem - * @Short_description: A menu item with an icon - * @Title: ImageMenuItem - * - * A ImageMenuItem is a menu item which has an icon next to the text label. - * - * Note that the user can disable display of menu icons, so make sure to still - * fill in the text label. - */ - - -struct _ImageMenuItemPrivate -{ - GtkWidget *image; - - gchar *label; - guint use_stock : 1; - guint toggle_size; -}; - -enum { - PROP_0, - PROP_IMAGE, - PROP_USE_STOCK, - PROP_ACCEL_GROUP, -}; - -static GtkActivatableIface *parent_activatable_iface; - -static void image_menu_item_destroy (GtkWidget *widget); -static void image_menu_item_get_preferred_width (GtkWidget *widget, - gint *minimum, - gint *natural); -static void image_menu_item_get_preferred_height (GtkWidget *widget, - gint *minimum, - gint *natural); -static void image_menu_item_get_preferred_height_for_width (GtkWidget *widget, - gint width, - gint *minimum, - gint *natural); -static void image_menu_item_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static void image_menu_item_map (GtkWidget *widget); -static void image_menu_item_remove (GtkContainer *container, - GtkWidget *child); -static void image_menu_item_toggle_size_request (GtkMenuItem *menu_item, - gint *requisition); -static void image_menu_item_set_label (GtkMenuItem *menu_item, - const gchar *label); -static const gchar * image_menu_item_get_label (GtkMenuItem *menu_item); - -static void image_menu_item_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); - -static void image_menu_item_finalize (GObject *object); -static void image_menu_item_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void image_menu_item_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void image_menu_item_screen_changed (GtkWidget *widget, - GdkScreen *previous_screen); - -static void image_menu_item_recalculate (ImageMenuItem *image_menu_item); - -static void image_menu_item_activatable_interface_init (GtkActivatableIface *iface); -static void image_menu_item_update (GtkActivatable *activatable, - GtkAction *action, - const gchar *property_name); -static void image_menu_item_sync_action_properties (GtkActivatable *activatable, - GtkAction *action); - - -G_DEFINE_TYPE_WITH_CODE (ImageMenuItem, image_menu_item, GTK_TYPE_MENU_ITEM, - G_ADD_PRIVATE (ImageMenuItem) - G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE, - image_menu_item_activatable_interface_init)) - - -static void -image_menu_item_class_init (ImageMenuItemClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass*) klass; - GtkWidgetClass *widget_class = (GtkWidgetClass*) klass; - GtkMenuItemClass *menu_item_class = (GtkMenuItemClass*) klass; - GtkContainerClass *container_class = (GtkContainerClass*) klass; - - widget_class->destroy = image_menu_item_destroy; - widget_class->screen_changed = image_menu_item_screen_changed; - widget_class->get_preferred_width = image_menu_item_get_preferred_width; - widget_class->get_preferred_height = image_menu_item_get_preferred_height; - widget_class->get_preferred_height_for_width = image_menu_item_get_preferred_height_for_width; - widget_class->size_allocate = image_menu_item_size_allocate; - widget_class->map = image_menu_item_map; - - container_class->forall = image_menu_item_forall; - container_class->remove = image_menu_item_remove; - - menu_item_class->toggle_size_request = image_menu_item_toggle_size_request; - menu_item_class->set_label = image_menu_item_set_label; - menu_item_class->get_label = image_menu_item_get_label; - - gobject_class->finalize = image_menu_item_finalize; - gobject_class->set_property = image_menu_item_set_property; - gobject_class->get_property = image_menu_item_get_property; - - /** - * ImageMenuItem:image: - * - * Child widget to appear next to the menu text. - * - */ - g_object_class_install_property (gobject_class, - PROP_IMAGE, - g_param_spec_object ("image", - _("Image widget"), - _("Child widget to appear next to the menu text"), - GTK_TYPE_WIDGET, - GTK_PARAM_READWRITE | G_PARAM_DEPRECATED)); - /** - * ImageMenuItem:use-stock: - * - * If %TRUE, the label set in the menuitem is used as a - * stock id to select the stock item for the item. - * - * Since: 2.16 - * - */ - g_object_class_install_property (gobject_class, - PROP_USE_STOCK, - g_param_spec_boolean ("use-stock", - _("Use stock"), - _("Whether to use the label text to create a stock menu item"), - FALSE, - GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_DEPRECATED)); - - /** - * ImageMenuItem:accel-group: - * - * The Accel Group to use for stock accelerator keys - * - * Since: 2.16 - * - */ - g_object_class_install_property (gobject_class, - PROP_ACCEL_GROUP, - g_param_spec_object ("accel-group", - _("Accel Group"), - _("The Accel Group to use for stock accelerator keys"), - GTK_TYPE_ACCEL_GROUP, - GTK_PARAM_WRITABLE | G_PARAM_DEPRECATED)); - -} - -static void -image_menu_item_init (ImageMenuItem *image_menu_item) -{ - ImageMenuItemPrivate *priv; - - image_menu_item->priv = image_menu_item_get_instance_private (image_menu_item); - priv = image_menu_item->priv; - - priv->image = NULL; - priv->use_stock = FALSE; - priv->label = NULL; -} - -static void -image_menu_item_finalize (GObject *object) -{ - ImageMenuItemPrivate *priv = IMAGE_MENU_ITEM (object)->priv; - - g_free (priv->label); - priv->label = NULL; - - G_OBJECT_CLASS (image_menu_item_parent_class)->finalize (object); -} - -static void -image_menu_item_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (object); - - switch (prop_id) - { - case PROP_IMAGE: - image_menu_item_set_image (image_menu_item, (GtkWidget *) g_value_get_object (value)); - break; - case PROP_USE_STOCK: - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - image_menu_item_set_use_stock (image_menu_item, g_value_get_boolean (value)); - G_GNUC_END_IGNORE_DEPRECATIONS; - break; - case PROP_ACCEL_GROUP: - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - image_menu_item_set_accel_group (image_menu_item, g_value_get_object (value)); - G_GNUC_END_IGNORE_DEPRECATIONS; - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -image_menu_item_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (object); - - switch (prop_id) - { - case PROP_IMAGE: - g_value_set_object (value, image_menu_item_get_image (image_menu_item)); - break; - case PROP_USE_STOCK: - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - g_value_set_boolean (value, image_menu_item_get_use_stock (image_menu_item)); - G_GNUC_END_IGNORE_DEPRECATIONS; - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -image_menu_item_map (GtkWidget *widget) -{ - ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (widget); - ImageMenuItemPrivate *priv = image_menu_item->priv; - - GTK_WIDGET_CLASS (image_menu_item_parent_class)->map (widget); - - if (priv->image) - g_object_set (priv->image, "visible", TRUE, NULL); -} - -static void -image_menu_item_destroy (GtkWidget *widget) -{ - ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (widget); - ImageMenuItemPrivate *priv = image_menu_item->priv; - - if (priv->image) - gtk_container_remove (GTK_CONTAINER (image_menu_item), - priv->image); - - GTK_WIDGET_CLASS (image_menu_item_parent_class)->destroy (widget); -} - -static void -image_menu_item_toggle_size_request (GtkMenuItem *menu_item, - gint *requisition) -{ - ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (menu_item); - ImageMenuItemPrivate *priv = image_menu_item->priv; - GtkPackDirection pack_dir; - GtkWidget *parent; - GtkWidget *widget = GTK_WIDGET (menu_item); - - parent = gtk_widget_get_parent (widget); - - if (GTK_IS_MENU_BAR (parent)) - pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent)); - else - pack_dir = GTK_PACK_DIRECTION_LTR; - - *requisition = 0; - - if (priv->image && gtk_widget_get_visible (priv->image)) - { - GtkRequisition image_requisition; - guint toggle_spacing; - - gtk_widget_get_preferred_size (priv->image, &image_requisition, NULL); - - gtk_widget_style_get (GTK_WIDGET (menu_item), - "toggle-spacing", &toggle_spacing, - NULL); - - if (pack_dir == GTK_PACK_DIRECTION_LTR || pack_dir == GTK_PACK_DIRECTION_RTL) - { - if (image_requisition.width > 0) - *requisition = image_requisition.width + toggle_spacing; - } - else - { - if (image_requisition.height > 0) - *requisition = image_requisition.height + toggle_spacing; - } - } -} - -static void -image_menu_item_recalculate (ImageMenuItem *image_menu_item) -{ - ImageMenuItemPrivate *priv = image_menu_item->priv; - GtkStockItem stock_item; - GtkWidget *image; - const gchar *resolved_label = priv->label; - - if (priv->use_stock && priv->label) - { - - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - - if (!priv->image) - { - image = gtk_image_new_from_stock (priv->label, GTK_ICON_SIZE_MENU); - image_menu_item_set_image (image_menu_item, image); - } - - if (gtk_stock_lookup (priv->label, &stock_item)) - resolved_label = stock_item.label; - - gtk_menu_item_set_use_underline (GTK_MENU_ITEM (image_menu_item), TRUE); - - G_GNUC_END_IGNORE_DEPRECATIONS; - } - - GTK_MENU_ITEM_CLASS - (image_menu_item_parent_class)->set_label (GTK_MENU_ITEM (image_menu_item), resolved_label); - -} - -static void -image_menu_item_set_label (GtkMenuItem *menu_item, - const gchar *label) -{ - ImageMenuItemPrivate *priv = IMAGE_MENU_ITEM (menu_item)->priv; - - if (priv->label != label) - { - g_free (priv->label); - priv->label = g_strdup (label); - - image_menu_item_recalculate (IMAGE_MENU_ITEM (menu_item)); - - g_object_notify (G_OBJECT (menu_item), "label"); - - } -} - -static const gchar * -image_menu_item_get_label (GtkMenuItem *menu_item) -{ - ImageMenuItemPrivate *priv = IMAGE_MENU_ITEM (menu_item)->priv; - - return priv->label; -} - -static void -image_menu_item_get_preferred_width (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (widget); - ImageMenuItemPrivate *priv = image_menu_item->priv; - GtkPackDirection pack_dir; - GtkWidget *parent; - - parent = gtk_widget_get_parent (widget); - - if (GTK_IS_MENU_BAR (parent)) - pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent)); - else - pack_dir = GTK_PACK_DIRECTION_LTR; - - GTK_WIDGET_CLASS (image_menu_item_parent_class)->get_preferred_width (widget, minimum, natural); - - if ((pack_dir == GTK_PACK_DIRECTION_TTB || pack_dir == GTK_PACK_DIRECTION_BTT) && - priv->image && - gtk_widget_get_visible (priv->image)) - { - gint child_minimum, child_natural; - - gtk_widget_get_preferred_width (priv->image, &child_minimum, &child_natural); - - *minimum = MAX (*minimum, child_minimum); - *natural = MAX (*natural, child_natural); - } -} - -static void -image_menu_item_get_preferred_height (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (widget); - ImageMenuItemPrivate *priv = image_menu_item->priv; - gint child_height = 0; - GtkPackDirection pack_dir; - GtkWidget *parent; - - parent = gtk_widget_get_parent (widget); - - if (GTK_IS_MENU_BAR (parent)) - pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent)); - else - pack_dir = GTK_PACK_DIRECTION_LTR; - - if (priv->image && gtk_widget_get_visible (priv->image)) - { - GtkRequisition child_requisition; - - gtk_widget_get_preferred_size (priv->image, &child_requisition, NULL); - - child_height = child_requisition.height; - } - - GTK_WIDGET_CLASS (image_menu_item_parent_class)->get_preferred_height (widget, minimum, natural); - - if (pack_dir == GTK_PACK_DIRECTION_RTL || pack_dir == GTK_PACK_DIRECTION_LTR) - { - *minimum = MAX (*minimum, child_height); - *natural = MAX (*natural, child_height); - } -} - -static void -image_menu_item_get_preferred_height_for_width (GtkWidget *widget, - gint width, - gint *minimum, - gint *natural) -{ - ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (widget); - ImageMenuItemPrivate *priv = image_menu_item->priv; - gint child_height = 0; - GtkPackDirection pack_dir; - GtkWidget *parent; - - parent = gtk_widget_get_parent (widget); - - if (GTK_IS_MENU_BAR (parent)) - pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent)); - else - pack_dir = GTK_PACK_DIRECTION_LTR; - - if (priv->image && gtk_widget_get_visible (priv->image)) - { - GtkRequisition child_requisition; - - gtk_widget_get_preferred_size (priv->image, &child_requisition, NULL); - - child_height = child_requisition.height; - } - - GTK_WIDGET_CLASS - (image_menu_item_parent_class)->get_preferred_height_for_width (widget, width, minimum, natural); - - if (pack_dir == GTK_PACK_DIRECTION_RTL || pack_dir == GTK_PACK_DIRECTION_LTR) - { - *minimum = MAX (*minimum, child_height); - *natural = MAX (*natural, child_height); - } -} - - -static void -image_menu_item_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (widget); - ImageMenuItemPrivate *priv = image_menu_item->priv; - GtkAllocation widget_allocation; - GtkPackDirection pack_dir; - GtkWidget *parent; - - parent = gtk_widget_get_parent (widget); - - if (GTK_IS_MENU_BAR (parent)) - pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent)); - else - pack_dir = GTK_PACK_DIRECTION_LTR; - - GTK_WIDGET_CLASS (image_menu_item_parent_class)->size_allocate (widget, allocation); - - if (priv->image && gtk_widget_get_visible (priv->image)) - { - gint x, y, offset; - GtkStyleContext *context; - GtkStateFlags state; - GtkBorder padding; - GtkRequisition child_requisition; - GtkAllocation child_allocation; - guint horizontal_padding, toggle_spacing; - gint toggle_size; - - toggle_size = image_menu_item->priv->toggle_size; - gtk_widget_style_get (widget, - "horizontal-padding", &horizontal_padding, - "toggle-spacing", &toggle_spacing, - NULL); - - /* Man this is lame hardcoding action, but I can't - * come up with a solution that's really better. - */ - - gtk_widget_get_preferred_size (priv->image, &child_requisition, NULL); - - gtk_widget_get_allocation (widget, &widget_allocation); - - context = gtk_widget_get_style_context (widget); - state = gtk_widget_get_state_flags (widget); - gtk_style_context_get_padding (context, state, &padding); - offset = gtk_container_get_border_width (GTK_CONTAINER (image_menu_item)); - - if (pack_dir == GTK_PACK_DIRECTION_LTR || - pack_dir == GTK_PACK_DIRECTION_RTL) - { - if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) == - (pack_dir == GTK_PACK_DIRECTION_LTR)) - x = offset + horizontal_padding + padding.left + - (toggle_size - toggle_spacing - child_requisition.width) / 2; - else - x = widget_allocation.width - offset - horizontal_padding - padding.right - - toggle_size + toggle_spacing + - (toggle_size - toggle_spacing - child_requisition.width) / 2; - - y = (widget_allocation.height - child_requisition.height) / 2; - } - else - { - if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) == - (pack_dir == GTK_PACK_DIRECTION_TTB)) - y = offset + horizontal_padding + padding.top + - (toggle_size - toggle_spacing - child_requisition.height) / 2; - else - y = widget_allocation.height - offset - horizontal_padding - padding.bottom - - toggle_size + toggle_spacing + - (toggle_size - toggle_spacing - child_requisition.height) / 2; - - x = (widget_allocation.width - child_requisition.width) / 2; - } - - child_allocation.width = child_requisition.width; - child_allocation.height = child_requisition.height; - child_allocation.x = widget_allocation.x + MAX (x, 0); - child_allocation.y = widget_allocation.y + MAX (y, 0); - - gtk_widget_size_allocate (priv->image, &child_allocation); - } -} - -static void -image_menu_item_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (container); - ImageMenuItemPrivate *priv = image_menu_item->priv; - - GTK_CONTAINER_CLASS (image_menu_item_parent_class)->forall (container, - include_internals, - callback, - callback_data); - - if (include_internals && priv->image) - (* callback) (priv->image, callback_data); -} - - -static void -image_menu_item_activatable_interface_init (GtkActivatableIface *iface) -{ - parent_activatable_iface = g_type_interface_peek_parent (iface); - iface->update = image_menu_item_update; - iface->sync_action_properties = image_menu_item_sync_action_properties; -} - -static gboolean -activatable_update_stock_id (ImageMenuItem *image_menu_item, GtkAction *action) -{ - GtkWidget *image; - const gchar *stock_id = gtk_action_get_stock_id (action); - - image = image_menu_item_get_image (image_menu_item); - - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - - if (GTK_IS_IMAGE (image) && - stock_id && gtk_icon_factory_lookup_default (stock_id)) - { - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - gtk_image_set_from_stock (GTK_IMAGE (image), stock_id, GTK_ICON_SIZE_MENU); - G_GNUC_END_IGNORE_DEPRECATIONS; - return TRUE; - } - - G_GNUC_END_IGNORE_DEPRECATIONS; - - return FALSE; -} - -static gboolean -activatable_update_gicon (ImageMenuItem *image_menu_item, GtkAction *action) -{ - GtkWidget *image; - GIcon *icon = gtk_action_get_gicon (action); - const gchar *stock_id; - gboolean ret = FALSE; - - stock_id = gtk_action_get_stock_id (action); - - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - - image = image_menu_item_get_image (image_menu_item); - - if (icon && GTK_IS_IMAGE (image) && - !(stock_id && gtk_icon_factory_lookup_default (stock_id))) - { - gtk_image_set_from_gicon (GTK_IMAGE (image), icon, GTK_ICON_SIZE_MENU); - ret = TRUE; - } - - G_GNUC_END_IGNORE_DEPRECATIONS; - - return ret; -} - -static void -activatable_update_icon_name (ImageMenuItem *image_menu_item, GtkAction *action) -{ - GtkWidget *image; - const gchar *icon_name = gtk_action_get_icon_name (action); - - image = image_menu_item_get_image (image_menu_item); - - if (GTK_IS_IMAGE (image) && - (gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY || - gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_ICON_NAME)) - { - gtk_image_set_from_icon_name (GTK_IMAGE (image), icon_name, GTK_ICON_SIZE_MENU); - } -} - -static void -image_menu_item_update (GtkActivatable *activatable, - GtkAction *action, - const gchar *property_name) -{ - ImageMenuItem *image_menu_item; - gboolean use_appearance; - - image_menu_item = IMAGE_MENU_ITEM (activatable); - - parent_activatable_iface->update (activatable, action, property_name); - - use_appearance = gtk_activatable_get_use_action_appearance (activatable); - if (!use_appearance) - return; - - if (strcmp (property_name, "stock-id") == 0) - activatable_update_stock_id (image_menu_item, action); - else if (strcmp (property_name, "gicon") == 0) - activatable_update_gicon (image_menu_item, action); - else if (strcmp (property_name, "icon-name") == 0) - activatable_update_icon_name (image_menu_item, action); -} - -static void -image_menu_item_sync_action_properties (GtkActivatable *activatable, - GtkAction *action) -{ - ImageMenuItem *image_menu_item; - GtkWidget *image; - gboolean use_appearance; - - image_menu_item = IMAGE_MENU_ITEM (activatable); - - parent_activatable_iface->sync_action_properties (activatable, action); - - if (!action) - return; - - use_appearance = gtk_activatable_get_use_action_appearance (activatable); - if (!use_appearance) - return; - - image = image_menu_item_get_image (image_menu_item); - if (image && !GTK_IS_IMAGE (image)) - { - image_menu_item_set_image (image_menu_item, NULL); - image = NULL; - } - - if (!image) - { - image = gtk_image_new (); - gtk_widget_show (image); - image_menu_item_set_image (IMAGE_MENU_ITEM (activatable), - image); - } - - if (!activatable_update_stock_id (image_menu_item, action) && - !activatable_update_gicon (image_menu_item, action)) - activatable_update_icon_name (image_menu_item, action); - -} - - -/** - * image_menu_item_new: - * - * Creates a new #ImageMenuItem with an empty label. - * - * Returns: a new #ImageMenuItem - * - */ -GtkWidget* -image_menu_item_new (void) -{ - return g_object_new (TYPE_IMAGE_MENU_ITEM, NULL); -} - -/** - * image_menu_item_new_with_label: - * @label: the text of the menu item. - * - * Creates a new #ImageMenuItem containing a label. - * - * Returns: a new #ImageMenuItem. - * - */ -GtkWidget* -image_menu_item_new_with_label (const gchar *label) -{ - return g_object_new (TYPE_IMAGE_MENU_ITEM, - "label", label, - NULL); -} - -/** - * image_menu_item_new_with_mnemonic: - * @label: the text of the menu item, with an underscore in front of the - * mnemonic character - * - * Creates a new #ImageMenuItem containing a label. The label - * will be created using gtk_label_new_with_mnemonic(), so underscores - * in @label indicate the mnemonic for the menu item. - * - * Returns: a new #ImageMenuItem - * - */ -GtkWidget* -image_menu_item_new_with_mnemonic (const gchar *label) -{ - return g_object_new (TYPE_IMAGE_MENU_ITEM, - "use-underline", TRUE, - "label", label, - NULL); -} - -/** - * image_menu_item_new_from_stock: - * @stock_id: the name of the stock item. - * @accel_group: (allow-none): the #GtkAccelGroup to add the menu items - * accelerator to, or %NULL. - * - * Creates a new #ImageMenuItem containing the image and text from a - * stock item. Some stock ids have preprocessor macros like #STOCK_OK - * and #STOCK_APPLY. - * - * If you want this menu item to have changeable accelerators, then pass in - * %NULL for accel_group. Next call gtk_menu_item_set_accel_path() with an - * appropriate path for the menu item, use gtk_stock_lookup() to look up the - * standard accelerator for the stock item, and if one is found, call - * gtk_accel_map_add_entry() to register it. - * - * Returns: a new #ImageMenuItem. - * - */ -GtkWidget* -image_menu_item_new_from_stock (const gchar *stock_id, - GtkAccelGroup *accel_group) -{ - return g_object_new (TYPE_IMAGE_MENU_ITEM, - "label", stock_id, - "use-stock", TRUE, - "accel-group", accel_group, - NULL); -} - -/** - * image_menu_item_set_use_stock: - * @image_menu_item: a #ImageMenuItem - * @use_stock: %TRUE if the menuitem should use a stock item - * - * If %TRUE, the label set in the menuitem is used as a - * stock id to select the stock item for the item. - * - * Since: 2.16 - * - */ -void -image_menu_item_set_use_stock (ImageMenuItem *image_menu_item, - gboolean use_stock) -{ - ImageMenuItemPrivate *priv; - - g_return_if_fail (IS_IMAGE_MENU_ITEM (image_menu_item)); - - priv = image_menu_item->priv; - - if (priv->use_stock != use_stock) - { - priv->use_stock = use_stock; - - image_menu_item_recalculate (image_menu_item); - - g_object_notify (G_OBJECT (image_menu_item), "use-stock"); - } -} - -/** - * image_menu_item_get_use_stock: - * @image_menu_item: a #ImageMenuItem - * - * Checks whether the label set in the menuitem is used as a - * stock id to select the stock item for the item. - * - * Returns: %TRUE if the label set in the menuitem is used as a - * stock id to select the stock item for the item - * - * Since: 2.16 - * - */ -gboolean -image_menu_item_get_use_stock (ImageMenuItem *image_menu_item) -{ - g_return_val_if_fail (IS_IMAGE_MENU_ITEM (image_menu_item), FALSE); - - return image_menu_item->priv->use_stock; -} - -/** - * image_menu_item_set_accel_group: - * @image_menu_item: a #ImageMenuItem - * @accel_group: the #GtkAccelGroup - * - * Specifies an @accel_group to add the menu items accelerator to - * (this only applies to stock items so a stock item must already - * be set, make sure to call image_menu_item_set_use_stock() - * and gtk_menu_item_set_label() with a valid stock item first). - * - * If you want this menu item to have changeable accelerators then - * you shouldnt need this (see image_menu_item_new_from_stock()). - * - * Since: 2.16 - * - */ -void -image_menu_item_set_accel_group (ImageMenuItem *image_menu_item, - GtkAccelGroup *accel_group) -{ - ImageMenuItemPrivate *priv; - GtkStockItem stock_item; - - /* Silent return for the constructor */ - if (!accel_group) - return; - - g_return_if_fail (IS_IMAGE_MENU_ITEM (image_menu_item)); - g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group)); - - priv = image_menu_item->priv; - - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - - if (priv->use_stock && priv->label && gtk_stock_lookup (priv->label, &stock_item)) - if (stock_item.keyval) - { - gtk_widget_add_accelerator (GTK_WIDGET (image_menu_item), - "activate", - accel_group, - stock_item.keyval, - stock_item.modifier, - GTK_ACCEL_VISIBLE); - - g_object_notify (G_OBJECT (image_menu_item), "accel-group"); - } - - G_GNUC_END_IGNORE_DEPRECATIONS; - -} - -/** - * image_menu_item_set_image: - * @image_menu_item: a #ImageMenuItem. - * @image: (allow-none): a widget to set as the image for the menu item. - * - * Sets the image of @image_menu_item to the given widget. - * Note that it depends on the show-menu-images setting whether - * the image will be displayed or not. - * - */ -void -image_menu_item_set_image (ImageMenuItem *image_menu_item, - GtkWidget *image) -{ - ImageMenuItemPrivate *priv; - - g_return_if_fail (IS_IMAGE_MENU_ITEM (image_menu_item)); - - priv = image_menu_item->priv; - - if (image == priv->image) - return; - - if (priv->image) - gtk_container_remove (GTK_CONTAINER (image_menu_item), - priv->image); - - priv->image = image; - - if (image == NULL) - return; - - gtk_widget_set_parent (image, GTK_WIDGET (image_menu_item)); - g_object_set (image, "visible", TRUE, "no-show-all", TRUE, NULL); - - g_object_notify (G_OBJECT (image_menu_item), "image"); -} - -/** - * image_menu_item_get_image: - * @image_menu_item: a #ImageMenuItem - * - * Gets the widget that is currently set as the image of @image_menu_item. - * See image_menu_item_set_image(). - * - * Return value: (transfer none): the widget set as image of @image_menu_item - * - **/ -GtkWidget* -image_menu_item_get_image (ImageMenuItem *image_menu_item) -{ - g_return_val_if_fail (IS_IMAGE_MENU_ITEM (image_menu_item), NULL); - - return image_menu_item->priv->image; -} - -static void -image_menu_item_remove (GtkContainer *container, - GtkWidget *child) -{ - ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (container); - ImageMenuItemPrivate *priv = image_menu_item->priv; - - if (child == priv->image) - { - gboolean widget_was_visible; - - widget_was_visible = gtk_widget_get_visible (child); - - gtk_widget_unparent (child); - priv->image = NULL; - - if (widget_was_visible && - gtk_widget_get_visible (GTK_WIDGET (container))) - gtk_widget_queue_resize (GTK_WIDGET (container)); - - g_object_notify (G_OBJECT (image_menu_item), "image"); - } - else - { - GTK_CONTAINER_CLASS (image_menu_item_parent_class)->remove (container, child); - } -} - -static void -show_image_change_notify (ImageMenuItem *image_menu_item) -{ - ImageMenuItemPrivate *priv = image_menu_item->priv; - - if (priv->image) - { - gtk_widget_show (priv->image); - } -} - -static void -traverse_container (GtkWidget *widget, - gpointer data) -{ - if (IS_IMAGE_MENU_ITEM (widget)) - show_image_change_notify (IMAGE_MENU_ITEM (widget)); - else if (GTK_IS_CONTAINER (widget)) - gtk_container_forall (GTK_CONTAINER (widget), traverse_container, NULL); -} - -static void -image_menu_item_setting_changed (GtkSettings *settings) -{ - GList *list, *l; - - list = gtk_window_list_toplevels (); - - for (l = list; l; l = l->next) - gtk_container_forall (GTK_CONTAINER (l->data), - traverse_container, NULL); - - g_list_free (list); -} - -static void -image_menu_item_screen_changed (GtkWidget *widget, - GdkScreen *previous_screen) -{ - GtkSettings *settings; - gulong show_image_connection; - - if (!gtk_widget_has_screen (widget)) - return; - - settings = gtk_widget_get_settings (widget); - - show_image_connection = - g_signal_handler_find (settings, G_SIGNAL_MATCH_FUNC, 0, 0, - NULL, image_menu_item_setting_changed, NULL); - - if (show_image_connection) - return; - - g_signal_connect (settings, "notify::gtk-menu-images", - G_CALLBACK (image_menu_item_setting_changed), NULL); - - show_image_change_notify (IMAGE_MENU_ITEM (widget)); -} diff --git a/src/widgets/image-menu-item.h b/src/widgets/image-menu-item.h deleted file mode 100644 index 61cc48f3a..000000000 --- a/src/widgets/image-menu-item.h +++ /dev/null @@ -1,81 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. - * Forked for , icons in menus are important to us. - */ - -#ifndef __IMAGE_MENU_ITEM_H__ -#define __IMAGE_MENU_ITEM_H__ - -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -#define GTK_PARAM_READABLE G_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB -#define GTK_PARAM_WRITABLE G_PARAM_WRITABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB -#define GTK_PARAM_READWRITE G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB - -#define TYPE_IMAGE_MENU_ITEM (image_menu_item_get_type ()) -#define IMAGE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_IMAGE_MENU_ITEM, ImageMenuItem)) -#define IMAGE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_IMAGE_MENU_ITEM, ImageMenuItemClass)) -#define IS_IMAGE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_IMAGE_MENU_ITEM)) -#define IS_IMAGE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_IMAGE_MENU_ITEM)) -#define IMAGE_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_IMAGE_MENU_ITEM, ImageMenuItemClass)) - -typedef struct _ImageMenuItem ImageMenuItem; -typedef struct _ImageMenuItemPrivate ImageMenuItemPrivate; -typedef struct _ImageMenuItemClass ImageMenuItemClass; - -struct _ImageMenuItem -{ - GtkMenuItem menu_item; - - /*< private >*/ - ImageMenuItemPrivate *priv; -}; - -struct _ImageMenuItemClass -{ - GtkMenuItemClass parent_class; - - /* Padding for future expansion */ - void (*_gtk_reserved1) (void); - void (*_gtk_reserved2) (void); - void (*_gtk_reserved3) (void); - void (*_gtk_reserved4) (void); -}; - -GType image_menu_item_get_type (void) G_GNUC_CONST; -GtkWidget* image_menu_item_new (void); -GtkWidget* image_menu_item_new_with_label (const gchar *label); -GtkWidget* image_menu_item_new_with_mnemonic (const gchar *label); -GtkWidget* image_menu_item_new_from_stock (const gchar *stock_id, - GtkAccelGroup *accel_group); -void image_menu_item_set_image (ImageMenuItem *image_menu_item, - GtkWidget *image); -GtkWidget* image_menu_item_get_image (ImageMenuItem *image_menu_item); -void image_menu_item_set_use_stock (ImageMenuItem *image_menu_item, - gboolean use_stock); -gboolean image_menu_item_get_use_stock (ImageMenuItem *image_menu_item); -void image_menu_item_set_accel_group (ImageMenuItem *image_menu_item, - GtkAccelGroup *accel_group); - -G_END_DECLS - -#endif /* __IMAGE_MENU_ITEM_H__ */ diff --git a/src/widgets/ink-action.cpp b/src/widgets/ink-action.cpp index ace99d9aa..8859306f1 100644 --- a/src/widgets/ink-action.cpp +++ b/src/widgets/ink-action.cpp @@ -1,20 +1,8 @@ +#include "ink-action.h" #include "widgets/icon.h" -#include "icon-size.h" -#include <glib/gi18n.h> - - -#include "widgets/ink-action.h" - -#include "widgets/button.h" #include <gtk/gtk.h> -#if GTK_CHECK_VERSION(3,0,0) - // Fork of gtk-imagemenuitem to continue support - #include "widgets/image-menu-item.h" - -#endif - static void ink_action_finalize( GObject* obj ); static void ink_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ); static void ink_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ); @@ -165,12 +153,7 @@ static GtkWidget* ink_action_create_menu_item( GtkAction* action ) if ( act->private_data->iconId ) { gchar* label = 0; g_object_get( G_OBJECT(act), "label", &label, NULL ); - -#if GTK_CHECK_VERSION(3,0,0) - item = image_menu_item_new_with_mnemonic( label ); -#else item = gtk_image_menu_item_new_with_mnemonic( label ); -#endif GtkWidget* child = sp_icon_new( Inkscape::ICON_SIZE_MENU, act->private_data->iconId ); // TODO this work-around is until SPIcon will live properly inside of a popup menu @@ -185,12 +168,7 @@ static GtkWidget* ink_action_create_menu_item( GtkAction* action ) } } gtk_widget_show_all( child ); - -#if GTK_CHECK_VERSION(3,0,0) - image_menu_item_set_image( IMAGE_MENU_ITEM(item), child ); -#else gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM(item), child ); -#endif g_free( label ); label = 0; @@ -225,454 +203,13 @@ static GtkWidget* ink_action_create_tool_item( GtkAction* action ) return item; } - - -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ - - -static void ink_toggle_action_finalize( GObject* obj ); -static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ); -static void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ); - -static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action ); -static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action ); - -static void ink_toggle_action_update_icon( InkToggleAction* action ); - -struct _InkToggleActionPrivate -{ - gchar* iconId; - Inkscape::IconSize iconSize; -}; - -#define INK_TOGGLE_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_TOGGLE_ACTION_TYPE, InkToggleActionPrivate ) ) - -G_DEFINE_TYPE(InkToggleAction, ink_toggle_action, GTK_TYPE_TOGGLE_ACTION); - -static void ink_toggle_action_class_init( InkToggleActionClass* klass ) -{ - if ( klass ) { - GObjectClass * objClass = G_OBJECT_CLASS( klass ); - - objClass->finalize = ink_toggle_action_finalize; - objClass->get_property = ink_toggle_action_get_property; - objClass->set_property = ink_toggle_action_set_property; - - klass->parent_class.parent_class.create_menu_item = ink_toggle_action_create_menu_item; - klass->parent_class.parent_class.create_tool_item = ink_toggle_action_create_tool_item; - /*klass->parent_class.connect_proxy = connect_proxy;*/ - /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/ - - g_object_class_install_property( objClass, - PROP_INK_ID, - g_param_spec_string( "iconId", - "Icon ID", - "The id for the icon", - "", - (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); - - g_object_class_install_property( objClass, - PROP_INK_SIZE, - g_param_spec_int( "iconSize", - "Icon Size", - "The size the icon", - (int)Inkscape::ICON_SIZE_MENU, - (int)99, - (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR, - (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); - - g_type_class_add_private( klass, sizeof(InkToggleActionClass) ); - } -} - -static void ink_toggle_action_init( InkToggleAction* action ) -{ - action->private_data = INK_TOGGLE_ACTION_GET_PRIVATE( action ); - action->private_data->iconId = 0; - action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR; -} - -static void ink_toggle_action_finalize( GObject* obj ) -{ - InkToggleAction* action = INK_TOGGLE_ACTION( obj ); - - g_free( action->private_data->iconId ); - g_free( action->private_data ); - -} - -InkToggleAction* ink_toggle_action_new( const gchar *name, - const gchar *label, - const gchar *tooltip, - const gchar *inkId, - Inkscape::IconSize size, - SPAttributeEnum attr) -{ - GObject* obj = (GObject*)g_object_new( INK_TOGGLE_ACTION_TYPE, - "name", name, - "label", label, - "tooltip", tooltip, - "iconId", inkId, - "iconSize", Inkscape::getRegisteredIconSize(size), - //"SP_ATTR_INKSCAPE", attr, // Why doesn't this work and do I need to use g_object_set_data below? - NULL ); - - g_object_set_data(obj, "SP_ATTR_INKSCAPE", GINT_TO_POINTER(attr)); - InkToggleAction* action = INK_TOGGLE_ACTION( obj ); - - return action; -} - -static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ) -{ - InkToggleAction* action = INK_TOGGLE_ACTION( obj ); - (void)action; - switch ( propId ) { - case PROP_INK_ID: - { - g_value_set_string( value, action->private_data->iconId ); - } - break; - - case PROP_INK_SIZE: - { - g_value_set_int( value, action->private_data->iconSize ); - } - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); - } -} - -void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ) -{ - InkToggleAction* action = INK_TOGGLE_ACTION( obj ); - (void)action; - switch ( propId ) { - case PROP_INK_ID: - { - gchar* tmp = action->private_data->iconId; - action->private_data->iconId = g_value_dup_string( value ); - g_free( tmp ); - - ink_toggle_action_update_icon( action ); - } - break; - - case PROP_INK_SIZE: - { - action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value ); - } - break; - - default: - { - G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); - } - } -} - -static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action ) -{ - GtkWidget* item = GTK_TOGGLE_ACTION_CLASS(ink_toggle_action_parent_class)->parent_class.create_menu_item(action); - - return item; -} - -static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action ) -{ - InkToggleAction* act = INK_TOGGLE_ACTION( action ); - - GtkWidget* item = GTK_TOGGLE_ACTION_CLASS(ink_toggle_action_parent_class)->parent_class.create_tool_item(action); - if ( GTK_IS_TOOL_BUTTON(item) ) { - GtkToolButton* button = GTK_TOOL_BUTTON(item); - if ( act->private_data->iconId ) { - GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId ); - -#if GTK_CHECK_VERSION(3,0,0) - gtk_widget_set_hexpand(child, FALSE); - gtk_widget_set_vexpand(child, FALSE); - gtk_tool_button_set_icon_widget(button, child); -#else - GtkWidget* align = gtk_alignment_new( 0.5, 0.5, 0.0, 0.0 ); - gtk_container_add( GTK_CONTAINER(align), child ); - gtk_tool_button_set_icon_widget( button, align ); -#endif - } else { - gchar *label = 0; - g_object_get( G_OBJECT(action), "short_label", &label, NULL ); - gtk_tool_button_set_label( button, label ); - g_free( label ); - label = 0; - } - } else { - // For now trigger a warning but don't do anything else - GtkToolButton* button = GTK_TOOL_BUTTON(item); - (void)button; - } - gtk_widget_show_all( item ); - - return item; -} - - -static void ink_toggle_action_update_icon( InkToggleAction* action ) -{ - if ( action ) { - GSList* proxies = gtk_action_get_proxies( GTK_ACTION(action) ); - while ( proxies ) { - if ( GTK_IS_TOOL_ITEM(proxies->data) ) { - if ( GTK_IS_TOOL_BUTTON(proxies->data) ) { - GtkToolButton* button = GTK_TOOL_BUTTON(proxies->data); - - GtkWidget* child = sp_icon_new( action->private_data->iconSize, action->private_data->iconId ); - -#if GTK_CHECK_VERSION(3,0,0) - gtk_widget_set_hexpand(child, FALSE); - gtk_widget_set_vexpand(child, FALSE); - gtk_widget_show_all(child); - gtk_tool_button_set_icon_widget(button, child); -#else - GtkWidget* align = gtk_alignment_new( 0.5, 0.5, 0.0, 0.0 ); - gtk_container_add( GTK_CONTAINER(align), child ); - gtk_widget_show_all( align ); - gtk_tool_button_set_icon_widget( button, align ); -#endif - } - } - - proxies = g_slist_next( proxies ); - } - } -} - - -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ - - -static void ink_radio_action_finalize( GObject* obj ); -static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ); -static void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ); - -static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action ); -static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action ); - -struct _InkRadioActionPrivate -{ - gchar* iconId; - Inkscape::IconSize iconSize; -}; - -#define INK_RADIO_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_RADIO_ACTION_TYPE, InkRadioActionPrivate ) ) - -G_DEFINE_TYPE(InkRadioAction, ink_radio_action, GTK_TYPE_RADIO_ACTION); - -static void ink_radio_action_class_init( InkRadioActionClass* klass ) -{ - if ( klass ) { - GObjectClass * objClass = G_OBJECT_CLASS( klass ); - - objClass->finalize = ink_radio_action_finalize; - objClass->get_property = ink_radio_action_get_property; - objClass->set_property = ink_radio_action_set_property; - - klass->parent_class.parent_class.parent_class.create_menu_item = ink_radio_action_create_menu_item; - klass->parent_class.parent_class.parent_class.create_tool_item = ink_radio_action_create_tool_item; - /*klass->parent_class.connect_proxy = connect_proxy;*/ - /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/ - - g_object_class_install_property( objClass, - PROP_INK_ID, - g_param_spec_string( "iconId", - "Icon ID", - "The id for the icon", - "", - (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); - - g_object_class_install_property( objClass, - PROP_INK_SIZE, - g_param_spec_int( "iconSize", - "Icon Size", - "The size the icon", - (int)Inkscape::ICON_SIZE_MENU, - (int)Inkscape::ICON_SIZE_DECORATION, - (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR, - (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); - - g_type_class_add_private( klass, sizeof(InkRadioActionClass) ); - } -} - -static void ink_radio_action_init( InkRadioAction* action ) -{ - action->private_data = INK_RADIO_ACTION_GET_PRIVATE( action ); - action->private_data->iconId = 0; - action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR; -} - -static void ink_radio_action_finalize( GObject* obj ) -{ - InkRadioAction* action = INK_RADIO_ACTION( obj ); - - g_free( action->private_data->iconId ); - g_free( action->private_data ); - -} - -InkRadioAction* ink_radio_action_new( const gchar *name, - const gchar *label, - const gchar *tooltip, - const gchar *inkId, - Inkscape::IconSize size ) -{ - GObject* obj = (GObject*)g_object_new( INK_RADIO_ACTION_TYPE, - "name", name, - "label", label, - "tooltip", tooltip, - "iconId", inkId, - "iconSize", Inkscape::getRegisteredIconSize(size), - NULL ); - - InkRadioAction* action = INK_RADIO_ACTION( obj ); - - return action; -} - -static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ) -{ - InkRadioAction* action = INK_RADIO_ACTION( obj ); - (void)action; - switch ( propId ) { - case PROP_INK_ID: - { - g_value_set_string( value, action->private_data->iconId ); - } - break; - - case PROP_INK_SIZE: - { - g_value_set_int( value, action->private_data->iconSize ); - } - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); - } -} - -void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ) -{ - InkRadioAction* action = INK_RADIO_ACTION( obj ); - (void)action; - switch ( propId ) { - case PROP_INK_ID: - { - gchar* tmp = action->private_data->iconId; - action->private_data->iconId = g_value_dup_string( value ); - g_free( tmp ); - } - break; - - case PROP_INK_SIZE: - { - action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value ); - } - break; - - default: - { - G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); - } - } -} - -static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action ) -{ - GtkWidget* item = GTK_RADIO_ACTION_CLASS(ink_radio_action_parent_class)->parent_class.parent_class.create_menu_item(action); - - return item; -} - -static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action ) -{ - InkRadioAction* act = INK_RADIO_ACTION( action ); - GtkWidget* item = GTK_RADIO_ACTION_CLASS(ink_radio_action_parent_class)->parent_class.parent_class.create_tool_item(action); - - if ( act->private_data->iconId ) { - if ( GTK_IS_TOOL_BUTTON(item) ) { - GtkToolButton* button = GTK_TOOL_BUTTON(item); - - GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId ); - -#if GTK_CHECK_VERSION(3,0,0) - gtk_widget_set_hexpand(child, FALSE); - gtk_widget_set_vexpand(child, FALSE); - gtk_tool_button_set_icon_widget(button, child); -#else - GtkWidget* align = gtk_alignment_new( 0.5, 0.5, 0.0, 0.0 ); - gtk_container_add( GTK_CONTAINER(align), child ); - gtk_tool_button_set_icon_widget( button, align ); -#endif - } else { - // For now trigger a warning but don't do anything else - GtkToolButton* button = GTK_TOOL_BUTTON(item); - (void)button; - } - } - - // TODO investigate if needed - gtk_widget_show_all( item ); - - return item; -} - - -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ - -// ToolMenu Action is happily derived from http://www.gtkforums.com/viewtopic.php?t=4215 - -G_DEFINE_TYPE(InkToolMenuAction, ink_tool_menu_action, INK_ACTION_TYPE); - -static void -ink_tool_menu_action_class_init (InkToolMenuActionClass *klass) -{ - GtkActionClass *action_class = GTK_ACTION_CLASS (klass); - action_class->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON; -} - -static void -ink_tool_menu_action_init (InkToolMenuAction* /*tma*/) -{ -} - -InkToolMenuAction * -ink_tool_menu_action_new (const gchar *name, - const gchar *label, - const gchar *tooltip, - const gchar *inkId, - Inkscape::IconSize size ) -{ - g_return_val_if_fail (name != NULL, NULL); - - GObject* obj = (GObject*)g_object_new( INK_TOOL_MENU_ACTION_TYPE, - "name", name, - "label", label, - "tooltip", tooltip, - "iconId", inkId, - "iconSize", size, - NULL ); - - InkToolMenuAction* action = INK_TOOL_MENU_ACTION( obj ); - - return action; -} +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/ink-action.h b/src/widgets/ink-action.h index ac5cb9873..738212c61 100644 --- a/src/widgets/ink-action.h +++ b/src/widgets/ink-action.h @@ -1,7 +1,6 @@ #ifndef SEEN_INK_ACTION #define SEEN_INK_ACTION - #include <gtk/gtk.h> #include "icon-size.h" #include "attributes.h" @@ -41,119 +40,16 @@ InkAction* ink_action_new( const gchar *name, Inkscape::IconSize size ); -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ - - -#define INK_TOGGLE_ACTION_TYPE ( ink_toggle_action_get_type() ) -#define INK_TOGGLE_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), INK_TOGGLE_ACTION_TYPE, InkToggleAction) ) -#define INK_TOGGLE_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), INK_TOGGLE_ACTION_TYPE, InkToggleActionClass) ) -#define IS_INK_TOGGLE_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), INK_TOGGLE_ACTION_TYPE) ) -#define IS_INK_TOGGLE_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), INK_TOGGLE_ACTION_TYPE) ) -#define INK_TOGGLE_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), INK_TOGGLE_ACTION_TYPE, InkToggleActionClass) ) - -typedef struct _InkToggleAction InkToggleAction; -typedef struct _InkToggleActionClass InkToggleActionClass; -typedef struct _InkToggleActionPrivate InkToggleActionPrivate; - -struct _InkToggleAction -{ - GtkToggleAction action; - InkToggleActionPrivate *private_data; -}; - -struct _InkToggleActionClass -{ - GtkToggleActionClass parent_class; -}; - -GType ink_toggle_action_get_type( void ); - -InkToggleAction* ink_toggle_action_new( const gchar *name, - const gchar *label, - const gchar *tooltip, - const gchar *inkId, - Inkscape::IconSize size, - SPAttributeEnum attr = SP_ATTR_INVALID); - - -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ - - -#define INK_RADIO_ACTION_TYPE ( ink_radio_action_get_type() ) -#define INK_RADIO_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), INK_RADIO_ACTION_TYPE, InkRadioAction) ) -#define INK_RADIO_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), INK_RADIO_ACTION_TYPE, InkRadioActionClass) ) -#define IS_INK_RADIO_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), INK_RADIO_ACTION_TYPE) ) -#define IS_INK_RADIO_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), INK_RADIO_ACTION_TYPE) ) -#define INK_RADIO_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), INK_RADIO_ACTION_TYPE, InkRadioActionClass) ) - -typedef struct _InkRadioAction InkRadioAction; -typedef struct _InkRadioActionClass InkRadioActionClass; -typedef struct _InkRadioActionPrivate InkRadioActionPrivate; - -struct _InkRadioAction -{ - GtkRadioAction action; - InkRadioActionPrivate *private_data; -}; - -struct _InkRadioActionClass -{ - GtkRadioActionClass parent_class; -}; - -GType ink_radio_action_get_type( void ); - -InkRadioAction* ink_radio_action_new( const gchar *name, - const gchar *label, - const gchar *tooltip, - const gchar *inkId, - Inkscape::IconSize size ); - - -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ -/* --------------------------------------------------------------- */ - -// ToolMenu Action is happily derived from http://www.gtkforums.com/viewtopic.php?t=4215 - -#define INK_TOOL_MENU_ACTION_TYPE ( ink_tool_menu_action_get_type() ) -#define INK_TOOL_MENU_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), INK_TOOL_MENU_ACTION_TYPE, InkToolMenuAction) ) -#define INK_TOOL_MENU_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), INK_TOOL_MENU_ACTION_TYPE, InkToolMenuActionClass) ) -#define IS_INK_TOOL_MENU_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), INK_TOOL_MENU_ACTION_TYPE) ) -#define IS_INK_TOOL_MENU_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), INK_TOOL_MENU_ACTION_TYPE) ) -#define INK_TOOL_MENU_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), INK_TOOL_MENU_ACTION_TYPE, InkToolMenuActionClass) ) - -typedef struct _InkToolMenuAction InkToolMenuAction; -typedef struct _InkToolMenuActionClass InkToolMenuActionClass; -typedef struct _InkToolMenuActionPrivate InkToolMenuActionPrivate; - -struct _InkToolMenuAction -{ - InkAction action; -}; - -struct _InkToolMenuActionClass -{ - InkActionClass parent_class; -}; - -GType ink_tool_menu_action_get_type( void ); - -InkToolMenuAction* ink_tool_menu_action_new( const gchar *name, - const gchar *label, - const gchar *tooltip, - const gchar *inkId, - Inkscape::IconSize size ); - - - G_END_DECLS #endif /* SEEN_INK_ACTION */ +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/ink-comboboxentry-action.cpp b/src/widgets/ink-comboboxentry-action.cpp index ec5e26cf5..2fecb06a4 100644 --- a/src/widgets/ink-comboboxentry-action.cpp +++ b/src/widgets/ink-comboboxentry-action.cpp @@ -371,16 +371,10 @@ GtkWidget* create_tool_item( GtkAction* action ) g_free( combobox_name ); { -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_halign(comboBoxEntry, GTK_ALIGN_START); gtk_widget_set_hexpand(comboBoxEntry, FALSE); gtk_widget_set_vexpand(comboBoxEntry, FALSE); gtk_container_add(GTK_CONTAINER(item), comboBoxEntry); -#else - GtkWidget *align = gtk_alignment_new(0, 0.5, 0, 0); - gtk_container_add( GTK_CONTAINER(align), comboBoxEntry ); - gtk_container_add( GTK_CONTAINER(item), align ); -#endif } ink_comboboxentry_action->combobox = GTK_COMBO_BOX (comboBoxEntry); @@ -414,11 +408,7 @@ GtkWidget* create_tool_item( GtkAction* action ) // Optionally widen the combobox width... which widens the drop-down list in list mode. if( ink_comboboxentry_action->extra_width > 0 ) { GtkRequisition req; -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_get_preferred_size(GTK_WIDGET(ink_comboboxentry_action->combobox), &req, NULL); -#else - gtk_widget_size_request( GTK_WIDGET( ink_comboboxentry_action->combobox ), &req ); -#endif gtk_widget_set_size_request( GTK_WIDGET( ink_comboboxentry_action->combobox ), req.width + ink_comboboxentry_action->extra_width, -1 ); } @@ -635,11 +625,7 @@ void ink_comboboxentry_action_set_extra_width( Ink_ComboBoxEntry_Action* action, // Widget may not have been created.... if( action->combobox ) { GtkRequisition req; -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_get_preferred_size(GTK_WIDGET(action->combobox), &req, NULL); -#else - gtk_widget_size_request( GTK_WIDGET( action->combobox ), &req ); -#endif gtk_widget_set_size_request( GTK_WIDGET( action->combobox ), req.width + action->extra_width, -1 ); } } diff --git a/src/widgets/ink-radio-action.cpp b/src/widgets/ink-radio-action.cpp new file mode 100644 index 000000000..2113819c3 --- /dev/null +++ b/src/widgets/ink-radio-action.cpp @@ -0,0 +1,185 @@ +#include "ink-radio-action.h" + +static void ink_radio_action_finalize( GObject* obj ); +static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ); +static void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ); + +static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action ); +static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action ); + +struct _InkRadioActionPrivate +{ + gchar* iconId; + Inkscape::IconSize iconSize; +}; + +#define INK_RADIO_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_RADIO_ACTION_TYPE, InkRadioActionPrivate ) ) + +G_DEFINE_TYPE(InkRadioAction, ink_radio_action, GTK_TYPE_RADIO_ACTION); + +enum { + PROP_INK_ID = 1, + PROP_INK_SIZE +}; + +static void ink_radio_action_class_init( InkRadioActionClass* klass ) +{ + if ( klass ) { + GObjectClass * objClass = G_OBJECT_CLASS( klass ); + + objClass->finalize = ink_radio_action_finalize; + objClass->get_property = ink_radio_action_get_property; + objClass->set_property = ink_radio_action_set_property; + + klass->parent_class.parent_class.parent_class.create_menu_item = ink_radio_action_create_menu_item; + klass->parent_class.parent_class.parent_class.create_tool_item = ink_radio_action_create_tool_item; + /*klass->parent_class.connect_proxy = connect_proxy;*/ + /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/ + + g_object_class_install_property( objClass, + PROP_INK_ID, + g_param_spec_string( "iconId", + "Icon ID", + "The id for the icon", + "", + (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); + + g_object_class_install_property( objClass, + PROP_INK_SIZE, + g_param_spec_int( "iconSize", + "Icon Size", + "The size the icon", + (int)Inkscape::ICON_SIZE_MENU, + (int)Inkscape::ICON_SIZE_DECORATION, + (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR, + (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); + + g_type_class_add_private( klass, sizeof(InkRadioActionClass) ); + } +} + +static void ink_radio_action_init( InkRadioAction* action ) +{ + action->private_data = INK_RADIO_ACTION_GET_PRIVATE( action ); + action->private_data->iconId = 0; + action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR; +} + +static void ink_radio_action_finalize( GObject* obj ) +{ + InkRadioAction* action = INK_RADIO_ACTION( obj ); + + g_free( action->private_data->iconId ); + g_free( action->private_data ); + +} + +InkRadioAction* ink_radio_action_new( const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *inkId, + Inkscape::IconSize size ) +{ + GObject* obj = (GObject*)g_object_new( INK_RADIO_ACTION_TYPE, + "name", name, + "label", label, + "tooltip", tooltip, + "iconId", inkId, + "iconSize", Inkscape::getRegisteredIconSize(size), + NULL ); + + InkRadioAction* action = INK_RADIO_ACTION( obj ); + + return action; +} + +static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ) +{ + InkRadioAction* action = INK_RADIO_ACTION( obj ); + (void)action; + switch ( propId ) { + case PROP_INK_ID: + { + g_value_set_string( value, action->private_data->iconId ); + } + break; + + case PROP_INK_SIZE: + { + g_value_set_int( value, action->private_data->iconSize ); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); + } +} + +void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ) +{ + InkRadioAction* action = INK_RADIO_ACTION( obj ); + (void)action; + switch ( propId ) { + case PROP_INK_ID: + { + gchar* tmp = action->private_data->iconId; + action->private_data->iconId = g_value_dup_string( value ); + g_free( tmp ); + } + break; + + case PROP_INK_SIZE: + { + action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value ); + } + break; + + default: + { + G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); + } + } +} + +static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action ) +{ + GtkWidget* item = GTK_RADIO_ACTION_CLASS(ink_radio_action_parent_class)->parent_class.parent_class.create_menu_item(action); + + return item; +} + +static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action ) +{ + InkRadioAction* act = INK_RADIO_ACTION( action ); + GtkWidget* item = GTK_RADIO_ACTION_CLASS(ink_radio_action_parent_class)->parent_class.parent_class.create_tool_item(action); + + if ( act->private_data->iconId ) { + if ( GTK_IS_TOOL_BUTTON(item) ) { + GtkToolButton* button = GTK_TOOL_BUTTON(item); + + GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId ); + gtk_widget_set_hexpand(child, FALSE); + gtk_widget_set_vexpand(child, FALSE); + gtk_tool_button_set_icon_widget(button, child); + } else { + // For now trigger a warning but don't do anything else + GtkToolButton* button = GTK_TOOL_BUTTON(item); + (void)button; + } + } + + // TODO investigate if needed + gtk_widget_show_all( item ); + + return item; +} +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/ink-radio-action.h b/src/widgets/ink-radio-action.h new file mode 100644 index 000000000..c1f059c4f --- /dev/null +++ b/src/widgets/ink-radio-action.h @@ -0,0 +1,52 @@ +#ifndef INK_RADIO_ACTION_H +#define INK_RADIO_ACTION_H + +#include <gtk/gtk.h> + +#include "icon.h" + +G_BEGIN_DECLS + +#define INK_RADIO_ACTION_TYPE ( ink_radio_action_get_type() ) +#define INK_RADIO_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), INK_RADIO_ACTION_TYPE, InkRadioAction) ) +#define INK_RADIO_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), INK_RADIO_ACTION_TYPE, InkRadioActionClass) ) +#define IS_INK_RADIO_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), INK_RADIO_ACTION_TYPE) ) +#define IS_INK_RADIO_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), INK_RADIO_ACTION_TYPE) ) +#define INK_RADIO_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), INK_RADIO_ACTION_TYPE, InkRadioActionClass) ) + +typedef struct _InkRadioAction InkRadioAction; +typedef struct _InkRadioActionClass InkRadioActionClass; +typedef struct _InkRadioActionPrivate InkRadioActionPrivate; + +struct _InkRadioAction +{ + GtkRadioAction action; + InkRadioActionPrivate *private_data; +}; + +struct _InkRadioActionClass +{ + GtkRadioActionClass parent_class; +}; + +GType ink_radio_action_get_type( void ); + +InkRadioAction* ink_radio_action_new( const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *inkId, + Inkscape::IconSize size ); + +G_END_DECLS + +#endif // INK_RADIO_ACTION_H +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/ink-toggle-action.cpp b/src/widgets/ink-toggle-action.cpp new file mode 100644 index 000000000..3eed974dc --- /dev/null +++ b/src/widgets/ink-toggle-action.cpp @@ -0,0 +1,221 @@ +#include "ink-toggle-action.h" +#include "icon.h" + +static void ink_toggle_action_finalize( GObject* obj ); +static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ); +static void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ); + +static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action ); +static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action ); + +static void ink_toggle_action_update_icon( InkToggleAction* action ); + +struct _InkToggleActionPrivate +{ + gchar* iconId; + Inkscape::IconSize iconSize; +}; + +#define INK_TOGGLE_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_TOGGLE_ACTION_TYPE, InkToggleActionPrivate ) ) + +G_DEFINE_TYPE(InkToggleAction, ink_toggle_action, GTK_TYPE_TOGGLE_ACTION); + +enum { + PROP_INK_ID = 1, + PROP_INK_SIZE +}; + +static void ink_toggle_action_class_init( InkToggleActionClass* klass ) +{ + if ( klass ) { + GObjectClass * objClass = G_OBJECT_CLASS( klass ); + + objClass->finalize = ink_toggle_action_finalize; + objClass->get_property = ink_toggle_action_get_property; + objClass->set_property = ink_toggle_action_set_property; + + klass->parent_class.parent_class.create_menu_item = ink_toggle_action_create_menu_item; + klass->parent_class.parent_class.create_tool_item = ink_toggle_action_create_tool_item; + /*klass->parent_class.connect_proxy = connect_proxy;*/ + /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/ + + g_object_class_install_property( objClass, + PROP_INK_ID, + g_param_spec_string( "iconId", + "Icon ID", + "The id for the icon", + "", + (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); + + g_object_class_install_property( objClass, + PROP_INK_SIZE, + g_param_spec_int( "iconSize", + "Icon Size", + "The size the icon", + (int)Inkscape::ICON_SIZE_MENU, + (int)99, + (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR, + (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); + + g_type_class_add_private( klass, sizeof(InkToggleActionClass) ); + } +} + +static void ink_toggle_action_init( InkToggleAction* action ) +{ + action->private_data = INK_TOGGLE_ACTION_GET_PRIVATE( action ); + action->private_data->iconId = 0; + action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR; +} + +static void ink_toggle_action_finalize( GObject* obj ) +{ + InkToggleAction* action = INK_TOGGLE_ACTION( obj ); + + g_free( action->private_data->iconId ); + g_free( action->private_data ); + +} + +InkToggleAction* ink_toggle_action_new( const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *inkId, + Inkscape::IconSize size, + SPAttributeEnum attr) +{ + GObject* obj = (GObject*)g_object_new( INK_TOGGLE_ACTION_TYPE, + "name", name, + "label", label, + "tooltip", tooltip, + "iconId", inkId, + "iconSize", Inkscape::getRegisteredIconSize(size), + //"SP_ATTR_INKSCAPE", attr, // Why doesn't this work and do I need to use g_object_set_data below? + NULL ); + + g_object_set_data(obj, "SP_ATTR_INKSCAPE", GINT_TO_POINTER(attr)); + InkToggleAction* action = INK_TOGGLE_ACTION( obj ); + + return action; +} + +static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ) +{ + InkToggleAction* action = INK_TOGGLE_ACTION( obj ); + (void)action; + switch ( propId ) { + case PROP_INK_ID: + { + g_value_set_string( value, action->private_data->iconId ); + } + break; + + case PROP_INK_SIZE: + { + g_value_set_int( value, action->private_data->iconSize ); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); + } +} + +void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ) +{ + InkToggleAction* action = INK_TOGGLE_ACTION( obj ); + (void)action; + switch ( propId ) { + case PROP_INK_ID: + { + gchar* tmp = action->private_data->iconId; + action->private_data->iconId = g_value_dup_string( value ); + g_free( tmp ); + + ink_toggle_action_update_icon( action ); + } + break; + + case PROP_INK_SIZE: + { + action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value ); + } + break; + + default: + { + G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); + } + } +} + +static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action ) +{ + GtkWidget* item = GTK_TOGGLE_ACTION_CLASS(ink_toggle_action_parent_class)->parent_class.create_menu_item(action); + + return item; +} + +static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action ) +{ + InkToggleAction* act = INK_TOGGLE_ACTION( action ); + + GtkWidget* item = GTK_TOGGLE_ACTION_CLASS(ink_toggle_action_parent_class)->parent_class.create_tool_item(action); + if ( GTK_IS_TOOL_BUTTON(item) ) { + GtkToolButton* button = GTK_TOOL_BUTTON(item); + if ( act->private_data->iconId ) { + GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId ); + + gtk_widget_set_hexpand(child, FALSE); + gtk_widget_set_vexpand(child, FALSE); + gtk_tool_button_set_icon_widget(button, child); + } else { + gchar *label = 0; + g_object_get( G_OBJECT(action), "short_label", &label, NULL ); + gtk_tool_button_set_label( button, label ); + g_free( label ); + label = 0; + } + } else { + // For now trigger a warning but don't do anything else + GtkToolButton* button = GTK_TOOL_BUTTON(item); + (void)button; + } + gtk_widget_show_all( item ); + + return item; +} + + +static void ink_toggle_action_update_icon( InkToggleAction* action ) +{ + if ( action ) { + GSList* proxies = gtk_action_get_proxies( GTK_ACTION(action) ); + while ( proxies ) { + if ( GTK_IS_TOOL_ITEM(proxies->data) ) { + if ( GTK_IS_TOOL_BUTTON(proxies->data) ) { + GtkToolButton* button = GTK_TOOL_BUTTON(proxies->data); + + GtkWidget* child = sp_icon_new( action->private_data->iconSize, action->private_data->iconId ); + gtk_widget_set_hexpand(child, FALSE); + gtk_widget_set_vexpand(child, FALSE); + gtk_widget_show_all(child); + gtk_tool_button_set_icon_widget(button, child); + } + } + + proxies = g_slist_next( proxies ); + } + } +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/ink-toggle-action.h b/src/widgets/ink-toggle-action.h new file mode 100644 index 000000000..8e9d5e257 --- /dev/null +++ b/src/widgets/ink-toggle-action.h @@ -0,0 +1,53 @@ +#ifndef INK_TOGGLE_ACTION_H +#define INK_TOGGLE_ACTION_H + +#include <gtk/gtk.h> + +#include "attributes.h" +#include "icon-size.h" + +G_BEGIN_DECLS +#define INK_TOGGLE_ACTION_TYPE ( ink_toggle_action_get_type() ) +#define INK_TOGGLE_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), INK_TOGGLE_ACTION_TYPE, InkToggleAction) ) +#define INK_TOGGLE_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), INK_TOGGLE_ACTION_TYPE, InkToggleActionClass) ) +#define IS_INK_TOGGLE_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), INK_TOGGLE_ACTION_TYPE) ) +#define IS_INK_TOGGLE_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), INK_TOGGLE_ACTION_TYPE) ) +#define INK_TOGGLE_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), INK_TOGGLE_ACTION_TYPE, InkToggleActionClass) ) + +typedef struct _InkToggleAction InkToggleAction; +typedef struct _InkToggleActionClass InkToggleActionClass; +typedef struct _InkToggleActionPrivate InkToggleActionPrivate; + +struct _InkToggleAction +{ + GtkToggleAction action; + InkToggleActionPrivate *private_data; +}; + +struct _InkToggleActionClass +{ + GtkToggleActionClass parent_class; +}; + +GType ink_toggle_action_get_type( void ); + +InkToggleAction* ink_toggle_action_new( const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *inkId, + Inkscape::IconSize size, + SPAttributeEnum attr = SP_ATTR_INVALID); + +G_END_DECLS + +#endif // INK_TOGGLE_ACTION_H +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/ink-tool-menu-action.cpp b/src/widgets/ink-tool-menu-action.cpp new file mode 100644 index 000000000..29d8dc92f --- /dev/null +++ b/src/widgets/ink-tool-menu-action.cpp @@ -0,0 +1,49 @@ +#include "ink-tool-menu-action.h" + +// ToolMenu Action is happily derived from http://www.gtkforums.com/viewtopic.php?t=4215 + +G_DEFINE_TYPE(InkToolMenuAction, ink_tool_menu_action, INK_ACTION_TYPE); + +static void +ink_tool_menu_action_class_init (InkToolMenuActionClass *klass) +{ + GtkActionClass *action_class = GTK_ACTION_CLASS (klass); + action_class->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON; +} + +static void +ink_tool_menu_action_init (InkToolMenuAction* /*tma*/) +{ +} + +InkToolMenuAction * +ink_tool_menu_action_new (const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *inkId, + Inkscape::IconSize size ) +{ + g_return_val_if_fail (name != NULL, NULL); + + GObject* obj = (GObject*)g_object_new( INK_TOOL_MENU_ACTION_TYPE, + "name", name, + "label", label, + "tooltip", tooltip, + "iconId", inkId, + "iconSize", size, + NULL ); + + InkToolMenuAction* action = INK_TOOL_MENU_ACTION( obj ); + + return action; +} +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/ink-tool-menu-action.h b/src/widgets/ink-tool-menu-action.h new file mode 100644 index 000000000..be04489d3 --- /dev/null +++ b/src/widgets/ink-tool-menu-action.h @@ -0,0 +1,52 @@ +#ifndef INK_TOOL_MENU_ACTION_H +#define INK_TOOL_MENU_ACTION_H + +#include "ink-action.h" + +// ToolMenu Action is happily derived from http://www.gtkforums.com/viewtopic.php?t=4215 + +G_BEGIN_DECLS + +#define INK_TOOL_MENU_ACTION_TYPE ( ink_tool_menu_action_get_type() ) +#define INK_TOOL_MENU_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), INK_TOOL_MENU_ACTION_TYPE, InkToolMenuAction) ) +#define INK_TOOL_MENU_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), INK_TOOL_MENU_ACTION_TYPE, InkToolMenuActionClass) ) +#define IS_INK_TOOL_MENU_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), INK_TOOL_MENU_ACTION_TYPE) ) +#define IS_INK_TOOL_MENU_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), INK_TOOL_MENU_ACTION_TYPE) ) +#define INK_TOOL_MENU_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), INK_TOOL_MENU_ACTION_TYPE, InkToolMenuActionClass) ) + +typedef struct _InkToolMenuAction InkToolMenuAction; +typedef struct _InkToolMenuActionClass InkToolMenuActionClass; +typedef struct _InkToolMenuActionPrivate InkToolMenuActionPrivate; + +struct _InkToolMenuAction +{ + InkAction action; +}; + +struct _InkToolMenuActionClass +{ + InkActionClass parent_class; +}; + +GType ink_tool_menu_action_get_type( void ); + +InkToolMenuAction* ink_tool_menu_action_new( const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *inkId, + Inkscape::IconSize size ); + +G_END_DECLS + +#endif // INK_TOOL_MENU_ACTION_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/lpe-toolbar.cpp b/src/widgets/lpe-toolbar.cpp index 387bf6dee..c714aba10 100644 --- a/src/widgets/lpe-toolbar.cpp +++ b/src/widgets/lpe-toolbar.cpp @@ -25,27 +25,20 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include "live_effects/lpe-line_segment.h" #include "lpe-toolbar.h" -#include "desktop.h" -#include "document-undo.h" #include "widgets/ege-select-one-action.h" #include "helper/action-context.h" #include "helper/action.h" -#include "widgets/ink-action.h" -#include "live_effects/effect.h" -#include "preferences.h" -#include "selection.h" -#include "sp-namedview.h" +#include "ink-radio-action.h" +#include "ink-toggle-action.h" #include "ui/tools-switch.h" #include "ui/tools/lpe-tool.h" #include "ui/widget/unit-tracker.h" -#include "util/units.h" -#include "verbs.h" using Inkscape::UI::Widget::UnitTracker; using Inkscape::Util::Unit; @@ -309,7 +302,7 @@ void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GO gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, 0, Inkscape::LivePathEffect::LPETypeConverter.get_label(type).c_str(), - 1, Inkscape::LivePathEffect::LPETypeConverter.get_label(type).c_str(), + 1, _(Inkscape::LivePathEffect::LPETypeConverter.get_label(type).c_str()), 2, lpesubtools[i].icon_name, -1 ); } diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 990989f4a..066c3fbfa 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <glibmm/i18n.h> @@ -38,9 +38,9 @@ #include "document-undo.h" #include "widgets/ege-adjustment-action.h" #include "widgets/ege-output-action.h" -#include "preferences.h" #include "toolbox.h" -#include "widgets/ink-action.h" +#include "ink-action.h" +#include "ink-toggle-action.h" #include "ui/icon-names.h" #include "ui/tools/measure-tool.h" #include "ui/widget/unit-tracker.h" @@ -326,7 +326,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G { eact = create_adjustment_action( "MeasureOffsetAction", _("Offset"), _("Offset:"), - _("The offset size"), + _("Mark dimension offset"), "/tools/measure/offset", 5.0, GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, 0.0, 90000.0, 1.0, 4.0, diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp index 3643ce00c..0ca1cc027 100644 --- a/src/widgets/mesh-toolbar.cpp +++ b/src/widgets/mesh-toolbar.cpp @@ -15,27 +15,24 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif -// REVIEW THESE AT END OF REWRITE +#include <gtkmm.h> + #include "ui/widget/color-preview.h" #include "toolbox.h" #include "mesh-toolbar.h" #include "verbs.h" -#include "macros.h" #include "widgets/button.h" -#include "widgets/widget-sizes.h" -#include "widgets/spw-utilities.h" #include "widgets/spinbutton-events.h" #include "widgets/gradient-vector.h" #include "widgets/gradient-image.h" #include "style.h" #include "inkscape.h" -#include "preferences.h" #include "document-private.h" #include "document-undo.h" #include "desktop.h" @@ -45,25 +42,20 @@ #include "ui/tools/gradient-tool.h" #include "ui/tools/mesh-tool.h" #include "gradient-drag.h" -#include "sp-mesh.h" +#include "sp-mesh-gradient.h" #include "gradient-chemistry.h" -#include "gradient-selector.h" -#include "selection.h" #include "ui/icon-names.h" #include "widgets/ege-adjustment-action.h" -#include "widgets/ege-output-action.h" #include "widgets/ege-select-one-action.h" -#include "widgets/ink-action.h" -#include "widgets/ink-comboboxentry-action.h" +#include "ink-action.h" +#include "ink-radio-action.h" +#include "ink-toggle-action.h" #include "sp-stop.h" #include "svg/css-ostringstream.h" -#include "svg/svg-color.h" #include "desktop-style.h" -#include "toolbox.h" - using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; using Inkscape::UI::PrefPusher; @@ -75,76 +67,79 @@ static bool blocked = false; //## Mesh ## //######################## -/* - * Get the current selection and dragger status from the desktop - */ -void ms_read_selection( Inkscape::Selection *selection, - SPMesh *&ms_selected, - bool &ms_selected_multi, - SPMeshType &ms_type, - bool &ms_type_multi ) + +// Get a list of selected meshes taking into account fill/stroke toggles +std::vector<SPMeshGradient *> ms_get_dt_selected_gradients(Inkscape::Selection *selection) { + std::vector<SPMeshGradient *> ms_selected; - // Read desktop selection - bool first = true; - ms_type = SP_MESH_TYPE_COONS; - - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - SPStyle *style = item->style; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool edit_fill = prefs->getBool("/tools/mesh/edit_fill", true); + bool edit_stroke = prefs->getBool("/tools/mesh/edit_stroke", true); - if (style && (style->fill.isPaintserver())) { - SPPaintServer *server = item->style->getFillPaintServer(); - if ( SP_IS_MESH(server) ) { + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i;// get the items gradient, not the getVector() version + SPStyle *style = item->style; - SPMesh *gradient = SP_MESH(server); // ->getVector(); - SPMeshType type = gradient->type; + if (style) { - if (gradient != ms_selected) { - if (ms_selected) { - ms_selected_multi = true; - } else { - ms_selected = gradient; - } + + if (edit_fill && style->fill.isPaintserver()) { + SPPaintServer *server = item->style->getFillPaintServer(); + SPMeshGradient *mesh = dynamic_cast<SPMeshGradient *>(server); + if (mesh) { + ms_selected.push_back(mesh); } - if( type != ms_type ) { - if (ms_type != SP_MESH_TYPE_COONS && !first) { - ms_type_multi = true; - } else { - ms_type = type; - } + } + + if (edit_stroke && style->stroke.isPaintserver()) { + SPPaintServer *server = item->style->getStrokePaintServer(); + SPMeshGradient *mesh = dynamic_cast<SPMeshGradient *>(server); + if (mesh) { + ms_selected.push_back(mesh); } - first = false; } } - if (style && (style->stroke.isPaintserver())) { - SPPaintServer *server = item->style->getStrokePaintServer(); - if ( SP_IS_MESH(server) ) { + } + return ms_selected; +} - SPMesh *gradient = SP_MESH(server); // ->getVector(); - SPMeshType type = gradient->type; - if (gradient != ms_selected) { - if (ms_selected) { - ms_selected_multi = true; - } else { - ms_selected = gradient; - } - } - if( type != ms_type ) { - if (ms_type != SP_MESH_TYPE_COONS && !first) { - ms_type_multi = true; - } else { - ms_type = type; - } - } - first = false; +/* + * Get the current selection status from the desktop + */ +void ms_read_selection( Inkscape::Selection *selection, + SPMeshGradient *&ms_selected, + bool &ms_selected_multi, + SPMeshType &ms_type, + bool &ms_type_multi ) +{ + ms_selected = NULL; + ms_selected_multi = false; + ms_type = SP_MESH_TYPE_COONS; + ms_type_multi = false; + + bool first = true; + + // Read desktop selection, taking into account fill/stroke toggles + std::vector<SPMeshGradient *> meshes = ms_get_dt_selected_gradients( selection ); + for (auto i = meshes.begin(); i != meshes.end(); ++i) { + if (first) { + ms_selected = (*i); + ms_type = (*i)->type; + first = false; + } else { + if (ms_selected != (*i)) { + ms_selected_multi = true; + } + if (ms_type != (*i)->type) { + ms_type_multi = true; } } } - } +} /* * Core function, setup all the widgets whenever something changes on the desktop @@ -173,7 +168,7 @@ static void ms_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointe // // Hide/show handles? // } - SPMesh *ms_selected = 0; + SPMeshGradient *ms_selected = 0; SPMeshType ms_type = SP_MESH_TYPE_COONS; bool ms_selected_multi = false; bool ms_type_multi = false; @@ -181,7 +176,7 @@ static void ms_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointe // std::cout << " type: " << ms_type << std::endl; EgeSelectOneAction* type = (EgeSelectOneAction *) g_object_get_data(G_OBJECT(widget), "mesh_select_type_action"); - gtk_action_set_sensitive( GTK_ACTION(type), (ms_selected && !ms_selected_multi) ); + gtk_action_set_sensitive( GTK_ACTION(type), (ms_selected && !ms_type_multi) ); if (ms_selected) { blocked = TRUE; ege_select_one_action_set_active( type, ms_type ); @@ -212,34 +207,6 @@ static void ms_defs_modified(SPObject * /*defs*/, guint /*flags*/, GObject *widg ms_tb_selection_changed(NULL, widget); } -void ms_get_dt_selected_gradient(Inkscape::Selection *selection, SPMesh *&ms_selected) -{ - SPMesh *gradient = 0; - - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i;// get the items gradient, not the getVector() version - SPStyle *style = item->style; - SPPaintServer *server = 0; - - if (style && (style->fill.isPaintserver())) { - server = item->style->getFillPaintServer(); - } - if (style && (style->stroke.isPaintserver())) { - server = item->style->getStrokePaintServer(); - } - - if ( SP_IS_MESH(server) ) { - gradient = SP_MESH(server); - } - } - - if (gradient) { - ms_selected = gradient; - } -} - - /* * Callback functions for user actions */ @@ -304,18 +271,17 @@ static void ms_type_changed(EgeSelectOneAction *act, GtkWidget *widget) SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop")); Inkscape::Selection *selection = desktop->getSelection(); - SPMesh *gradient = 0; - ms_get_dt_selected_gradient(selection, gradient); + std::vector<SPMeshGradient *> meshes = ms_get_dt_selected_gradients(selection); - if (gradient) { - SPMeshType type = (SPMeshType) ege_select_one_action_get_active(act); + SPMeshType type = (SPMeshType) ege_select_one_action_get_active(act); + for (auto i = meshes.begin(); i != meshes.end(); ++i) { // std::cout << " type: " << type << std::endl; - gradient->type = type; - gradient->type_set = true; - gradient->updateRepr(); - - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH, - _("Set mesh type")); + (*i)->type = type; + (*i)->type_set = true; + (*i)->updateRepr(); + } + if (!meshes.empty() ) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH,_("Set mesh type")); } } @@ -357,6 +323,49 @@ static void ms_pick_colors(void) } } +static void ms_fit_mesh(void) +{ + MeshTool *mt = get_mesh_tool(); + if (mt) { + sp_mesh_context_fit_mesh_in_bbox( mt ); + } +} + +static void ms_toggle_handles(void) +{ + MeshTool *mt = get_mesh_tool(); + if (mt) { + GrDrag *drag = mt->_grdrag; + drag->refreshDraggers(); + } +} + +static void ms_toggle_fill_stroke(InkToggleAction * /*act*/, gpointer data) +{ + MeshTool *mt = get_mesh_tool(); + if (mt) { + GrDrag *drag = mt->_grdrag; + drag->updateDraggers(); + drag->updateLines(); + drag->updateLevels(); + ms_tb_selection_changed(NULL, data); // Need to update Type widget + } +} + +static void ms_warning_popup(void) +{ + char *msg = _("Mesh gradients are part of SVG 2:\n" + "* Syntax may change.\n" + "* Web browser implementation is not guaranteed.\n" + "\n" + "For web: convert to bitmap (Edit->Make bitmap copy).\n" + "For print: export to PDF."); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_WARNING, + Gtk::BUTTONS_OK, true); + dialog.run(); + +} + static void mesh_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); /** @@ -473,6 +482,7 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/mesh/edit_fill"); g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), holder); } /* Edit stroke mesh */ @@ -485,18 +495,20 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/mesh/edit_stroke"); g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), holder); } /* Show/hide side and tensor handles */ { InkToggleAction* act = ink_toggle_action_new( "MeshShowHandlesAction", _("Show Handles"), - _("Show side and tensor handles"), + _("Show handles"), INKSCAPE_ICON("show-node-handles"), secondarySize ); gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/mesh/show_handles"); g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_handles), 0); } g_object_set_data(holder, "desktop", desktop); @@ -505,9 +517,14 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj /* Warning */ { - GtkAction* act = gtk_action_new( "MeshWarningAction", - _("WARNING: Mesh SVG Syntax Subject to Change"), NULL, NULL ); + InkAction* act = ink_action_new( "MeshWarningAction", + _("WARNING: Mesh SVG Syntax Subject to Change"), + _("WARNING: Mesh SVG Syntax Subject to Change"), + INKSCAPE_ICON("dialog-warning"), + secondarySize ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_warning_popup), holder ); + gtk_action_set_sensitive( GTK_ACTION(act), TRUE ); } /* Type */ @@ -521,6 +538,7 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, 0, _("Bicubic"), 1, SP_MESH_TYPE_BICUBIC, -1 ); + // TRANSLATORS: Type of Smoothing. See https://en.wikipedia.org/wiki/Coons_patch EgeSelectOneAction* act = ege_select_one_action_new( "MeshSmoothAction", _("Coons"), _("Coons: no smoothing. Bicubic: smoothing across patch boundaries."), NULL, GTK_TREE_MODEL(model) ); @@ -566,6 +584,17 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj } + { + InkAction* act = ink_action_new( "MeshFitInBoundingBoxAction", + _("Scale mesh to bounding box:"), + _("Scale mesh to fit inside bounding box."), + INKSCAPE_ICON("mesh-gradient-fit"), + secondarySize ); + g_object_set( act, "short_label", _("Fit mesh"), NULL ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_fit_mesh), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + } static void mesh_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) diff --git a/src/widgets/node-toolbar.cpp b/src/widgets/node-toolbar.cpp index 113061519..31efaa0b4 100644 --- a/src/widgets/node-toolbar.cpp +++ b/src/widgets/node-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include "ui/tool/multi-path-manipulator.h" @@ -35,18 +35,16 @@ #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" -#include "widgets/ink-action.h" +#include "ink-toggle-action.h" +#include "ink-tool-menu-action.h" #include "inkscape.h" -#include "preferences.h" #include "selection-chemistry.h" -#include "selection.h" #include "sp-namedview.h" #include "toolbox.h" #include "ui/icon-names.h" #include "ui/tool/control-point-selection.h" #include "ui/tools/node-tool.h" #include "ui/widget/unit-tracker.h" -#include "util/units.h" #include "verbs.h" #include "widgets/widget-sizes.h" diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index 58a178aec..855371ddd 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -33,7 +33,7 @@ #include "sp-linear-gradient.h" #include "sp-radial-gradient.h" -#include "sp-mesh.h" +#include "sp-mesh-gradient.h" #include "sp-stop.h" /* fixme: Move it from dialogs to here */ #include "gradient-selector.h" @@ -41,7 +41,6 @@ #include <document-private.h> #include <desktop-style.h> #include <style.h> -#include "svg/svg-color.h" #include "svg/css-ostringstream.h" #include "path-prefix.h" #include "io/sys.h" @@ -55,8 +54,6 @@ #include "svg/svg-icc-color.h" #endif // SP_PS_VERBOSE -#include <gtk/gtk.h> - using Inkscape::Widgets::SwatchSelector; using Inkscape::UI::SelectedColor; @@ -81,6 +78,9 @@ static void sp_paint_selector_set_mode_multiple(SPPaintSelector *psel); static void sp_paint_selector_set_mode_none(SPPaintSelector *psel); static void sp_paint_selector_set_mode_color(SPPaintSelector *psel, SPPaintSelector::Mode mode); static void sp_paint_selector_set_mode_gradient(SPPaintSelector *psel, SPPaintSelector::Mode mode); +#ifdef WITH_MESH +static void sp_paint_selector_set_mode_mesh(SPPaintSelector *psel, SPPaintSelector::Mode mode); +#endif static void sp_paint_selector_set_mode_pattern(SPPaintSelector *psel, SPPaintSelector::Mode mode); static void sp_paint_selector_set_mode_swatch(SPPaintSelector *psel, SPPaintSelector::Mode mode); static void sp_paint_selector_set_mode_unset(SPPaintSelector *psel); @@ -98,12 +98,14 @@ static gchar const* modeStrings[] = { "MODE_SOLID_COLOR", "MODE_GRADIENT_LINEAR", "MODE_GRADIENT_RADIAL", +#ifdef WITH_MESH + "MODE_GRADIENT_MESH", +#endif "MODE_PATTERN", "MODE_SWATCH", "MODE_UNSET", ".", ".", - ".", }; #endif @@ -112,9 +114,6 @@ static bool isPaintModeGradient(SPPaintSelector::Mode mode) { bool isGrad = (mode == SPPaintSelector::MODE_GRADIENT_LINEAR) || (mode == SPPaintSelector::MODE_GRADIENT_RADIAL) || -#ifdef WITH_MESH - (mode == SPPaintSelector::MODE_GRADIENT_MESH) || -#endif (mode == SPPaintSelector::MODE_SWATCH); return isGrad; @@ -134,11 +133,7 @@ static SPGradientSelector *getGradientFromData(SPPaintSelector const *psel) return grad; } -#if GTK_CHECK_VERSION(3,0,0) G_DEFINE_TYPE(SPPaintSelector, sp_paint_selector, GTK_TYPE_BOX); -#else -G_DEFINE_TYPE(SPPaintSelector, sp_paint_selector, GTK_TYPE_VBOX); -#endif static void sp_paint_selector_class_init(SPPaintSelectorClass *klass) @@ -197,19 +192,13 @@ sp_paint_selector_class_init(SPPaintSelectorClass *klass) static void sp_paint_selector_init(SPPaintSelector *psel) { -#if GTK_CHECK_VERSION(3,0,0) gtk_orientable_set_orientation(GTK_ORIENTABLE(psel), GTK_ORIENTATION_VERTICAL); -#endif psel->mode = static_cast<SPPaintSelector::Mode>(-1); // huh? do you mean 0xff? -- I think this means "not in the enum" /* Paint style button box */ -#if GTK_CHECK_VERSION(3,0,0) psel->style = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(psel->style), FALSE); -#else - psel->style = gtk_hbox_new(FALSE, 0); -#endif gtk_widget_show(psel->style); gtk_container_set_border_width(GTK_CONTAINER(psel->style), 4); gtk_box_pack_start(GTK_BOX(psel), psel->style, FALSE, FALSE, 0); @@ -236,12 +225,8 @@ sp_paint_selector_init(SPPaintSelector *psel) /* Fillrule */ { -#if GTK_CHECK_VERSION(3,0,0) - psel->fillrulebox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_set_homogeneous(GTK_BOX(psel->fillrulebox), FALSE); -#else - psel->fillrulebox = gtk_hbox_new(FALSE, 0); -#endif + psel->fillrulebox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_set_homogeneous(GTK_BOX(psel->fillrulebox), FALSE); gtk_box_pack_end(GTK_BOX(psel->style), psel->fillrulebox, FALSE, FALSE, 0); GtkWidget *w; @@ -270,22 +255,14 @@ sp_paint_selector_init(SPPaintSelector *psel) /* Frame */ psel->label = gtk_label_new(""); -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *lbbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); + auto lbbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); gtk_box_set_homogeneous(GTK_BOX(lbbox), FALSE); -#else - GtkWidget *lbbox = gtk_hbox_new(FALSE, 4); -#endif gtk_widget_show(psel->label); gtk_box_pack_start(GTK_BOX(lbbox), psel->label, false, false, 4); gtk_box_pack_start(GTK_BOX(psel), lbbox, false, false, 4); -#if GTK_CHECK_VERSION(3,0,0) psel->frame = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); gtk_box_set_homogeneous(GTK_BOX(psel->frame), FALSE); -#else - psel->frame = gtk_vbox_new(FALSE, 4); -#endif gtk_widget_show(psel->frame); //gtk_container_set_border_width(GTK_CONTAINER(psel->frame), 0); gtk_box_pack_start(GTK_BOX(psel), psel->frame, TRUE, TRUE, 0); @@ -308,6 +285,11 @@ static void sp_paint_selector_dispose(GObject *object) // clean up our long-living pattern menu g_object_set_data(G_OBJECT(psel),"patternmenu",NULL); +#ifdef WITH_MESH + // clean up our long-living mesh menu + g_object_set_data(G_OBJECT(psel),"meshmenu",NULL); +#endif + if (psel->selected_color) { delete psel->selected_color; psel->selected_color = NULL; @@ -411,11 +393,13 @@ void SPPaintSelector::setMode(Mode mode) break; case MODE_GRADIENT_LINEAR: case MODE_GRADIENT_RADIAL: + sp_paint_selector_set_mode_gradient(this, mode); + break; #ifdef WITH_MESH case MODE_GRADIENT_MESH: -#endif - sp_paint_selector_set_mode_gradient(this, mode); + sp_paint_selector_set_mode_mesh(this, mode); break; +#endif case MODE_PATTERN: sp_paint_selector_set_mode_pattern(this, mode); break; @@ -513,17 +497,17 @@ void SPPaintSelector::setGradientRadial(SPGradient *vector) } #ifdef WITH_MESH -void SPPaintSelector::setGradientMesh(SPGradient *vector) +void SPPaintSelector::setGradientMesh(SPMeshGradient *array) { #ifdef SP_PS_VERBOSE g_print("PaintSelector set GRADIENT MESH\n"); #endif - setMode(MODE_GRADIENT_RADIAL); + setMode(MODE_GRADIENT_MESH); - SPGradientSelector *gsel = getGradientFromData(this); + // SPGradientSelector *gsel = getGradientFromData(this); - gsel->setMode(SPGradientSelector::MODE_MESH); - gsel->setVector((vector) ? vector->document : 0, vector); + // gsel->setMode(SPGradientSelector::MODE_GRADIENT_MESH); + // gsel->setVector((mesh) ? mesh->document : 0, mesh); } #endif @@ -545,6 +529,7 @@ void SPPaintSelector::getGradientProperties( SPGradientUnits &units, SPGradientS spread = gsel->getSpread(); } + /** * \post (alpha == NULL) || (*alpha in [0.0, 1.0]). */ @@ -700,12 +685,8 @@ static void sp_paint_selector_set_mode_color(SPPaintSelector *psel, SPPaintSelec sp_paint_selector_clear_frame(psel); /* Create new color selector */ /* Create vbox */ -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); - gtk_box_set_homogeneous(GTK_BOX(vb), FALSE); -#else - GtkWidget *vb = gtk_vbox_new(FALSE, 4); -#endif + auto vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); + gtk_box_set_homogeneous(GTK_BOX(vb), FALSE); gtk_widget_show(vb); /* Color selector */ @@ -759,11 +740,6 @@ static void sp_paint_selector_set_mode_gradient(SPPaintSelector *psel, SPPaintSe } else if (mode == SPPaintSelector::MODE_GRADIENT_RADIAL) { sp_paint_selector_set_style_buttons(psel, psel->radial); } -#ifdef WITH_MESH - else { - sp_paint_selector_set_style_buttons(psel, psel->mesh); - } -#endif gtk_widget_set_sensitive(psel->style, TRUE); if ((psel->mode == SPPaintSelector::MODE_GRADIENT_LINEAR) || (psel->mode == SPPaintSelector::MODE_GRADIENT_RADIAL)) { @@ -793,18 +769,347 @@ static void sp_paint_selector_set_mode_gradient(SPPaintSelector *psel, SPPaintSe SP_GRADIENT_SELECTOR(gsel)->setMode(SPGradientSelector::MODE_RADIAL); gtk_label_set_markup(GTK_LABEL(psel->label), _("<b>Radial gradient</b>")); } + +#ifdef SP_PS_VERBOSE + g_print("Gradient req\n"); +#endif +} + +// ************************* MESH ************************ #ifdef WITH_MESH - else { - SP_GRADIENT_SELECTOR(gsel)->setMode(SPGradientSelector::MODE_MESH); - gtk_label_set_markup(GTK_LABEL(psel->label), _("<b>Mesh gradient</b>")); +static void sp_psel_mesh_destroy(GtkWidget *widget, SPPaintSelector * /*psel*/) +{ + // drop our reference to the mesh menu widget + g_object_unref( G_OBJECT(widget) ); +} + +static void sp_psel_mesh_change(GtkWidget * /*widget*/, SPPaintSelector *psel) +{ + g_signal_emit(G_OBJECT(psel), psel_signals[CHANGED], 0); +} + + +/** + * Returns a list of meshes in the defs of the given source document as a GSList object + * Returns NULL if there are no meshes in the document. + */ +static GSList * +ink_mesh_list_get (SPDocument *source) +{ + if (source == NULL) + return NULL; + + GSList *pl = NULL; + std::vector<SPObject *> meshes = source->getResourceList("gradient"); + for (std::vector<SPObject *>::const_iterator it = meshes.begin(); it != meshes.end(); ++it) { + if (SP_IS_MESHGRADIENT(*it) && + SP_GRADIENT(*it) == SP_GRADIENT(*it)->getArray()) { // only if this is a root mesh + pl = g_slist_prepend(pl, *it); + } } -#endif + pl = g_slist_reverse(pl); + return pl; +} + +/** + * Adds menu items for mesh list. + */ +static void +sp_mesh_menu_build (GtkWidget *combo, GSList *mesh_list, SPDocument */*source*/) +{ + GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo))); + GtkTreeIter iter; + + for (; mesh_list != NULL; mesh_list = mesh_list->next) { + + Inkscape::XML::Node *repr = reinterpret_cast<SPItem *>(mesh_list->data)->getRepr(); + + gchar const *meshid = repr->attribute("id"); + gchar const *label = meshid; + + // Only relevant if we supply a set of canned meshes. + gboolean stockid = false; + if (repr->attribute("inkscape:stockid")) { + label = _(repr->attribute("inkscape:stockid")); + stockid = true; + } + + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + COMBO_COL_LABEL, label, COMBO_COL_STOCK, stockid, COMBO_COL_MESH, meshid, COMBO_COL_SEP, FALSE, -1); + + } +} + +/** + * Pick up all meshes from source, except those that are in + * current_doc (if non-NULL), and add items to the mesh menu. + */ +static void sp_mesh_list_from_doc(GtkWidget *combo, SPDocument * /*current_doc*/, SPDocument *source, SPDocument * /*mesh_doc*/) +{ + GSList *pl = ink_mesh_list_get(source); + GSList *clean_pl = NULL; + + for (; pl != NULL; pl = pl->next) { + if (!SP_IS_MESHGRADIENT(pl->data)) { + continue; + } + // Add to the list of meshes we really do wish to show + clean_pl = g_slist_prepend (clean_pl, pl->data); + } + + sp_mesh_menu_build (combo, clean_pl, source); + + g_slist_free (pl); + g_slist_free (clean_pl); +} + + +static void +ink_mesh_menu_populate_menu(GtkWidget *combo, SPDocument *doc) +{ + static SPDocument *meshes_doc = NULL; + + // If we ever add a list of canned mesh gradients, uncomment following: + + // find and load meshes.svg + // if (meshes_doc == NULL) { + // char *meshes_source = g_build_filename(INKSCAPE_MESHESDIR, "meshes.svg", NULL); + // if (Inkscape::IO::file_test(meshes_source, G_FILE_TEST_IS_REGULAR)) { + // meshes_doc = SPDocument::createNewDoc(meshes_source, FALSE); + // } + // g_free(meshes_source); + // } + + // suck in from current doc + sp_mesh_list_from_doc ( combo, NULL, doc, meshes_doc ); + + // add separator + // { + // GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo))); + // GtkTreeIter iter; + // gtk_list_store_append (store, &iter); + // gtk_list_store_set(store, &iter, + // COMBO_COL_LABEL, "", COMBO_COL_STOCK, false, COMBO_COL_MESH, "", COMBO_COL_SEP, true, -1); + // } + + // suck in from meshes.svg + // if (meshes_doc) { + // doc->ensureUpToDate(); + // sp_mesh_list_from_doc ( combo, doc, meshes_doc, NULL ); + // } + +} + + +static GtkWidget* +ink_mesh_menu(GtkWidget *combo) +{ + SPDocument *doc = SP_ACTIVE_DOCUMENT; + + GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo))); + GtkTreeIter iter; + + if (!doc) { + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + COMBO_COL_LABEL, _("No document selected"), COMBO_COL_STOCK, false, COMBO_COL_MESH, "", COMBO_COL_SEP, false, -1); + gtk_widget_set_sensitive(combo, FALSE); + + } else { + + ink_mesh_menu_populate_menu(combo, doc); + gtk_widget_set_sensitive(combo, TRUE); + + } + + // Select the first item that is not a separator + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL(store), &iter)) { + gboolean sep = false; + gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, COMBO_COL_SEP, &sep, -1); + if (sep) { + gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); + } + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), &iter); + } + + return combo; +} + + +/*update mesh list*/ +void SPPaintSelector::updateMeshList( SPMeshGradient *mesh ) +{ + if (update) { + return; + } + + GtkWidget *combo = GTK_WIDGET(g_object_get_data(G_OBJECT(this), "meshmenu")); + g_assert( combo != NULL ); + + /* Clear existing menu if any */ + GtkTreeModel *store = gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); + gtk_list_store_clear(GTK_LIST_STORE(store)); + + ink_mesh_menu(combo); + + /* Set history */ + + if (mesh && !g_object_get_data(G_OBJECT(combo), "update")) { + + g_object_set_data(G_OBJECT(combo), "update", GINT_TO_POINTER(TRUE)); + gchar const *meshname = mesh->getRepr()->attribute("id"); + + // Find this mesh and set it active in the combo_box + GtkTreeIter iter ; + gchar *meshid = NULL; + bool valid = gtk_tree_model_get_iter_first (store, &iter); + if (!valid) { + return; + } + gtk_tree_model_get (store, &iter, COMBO_COL_MESH, &meshid, -1); + while (valid && strcmp(meshid, meshname) != 0) { + valid = gtk_tree_model_iter_next (store, &iter); + gtk_tree_model_get (store, &iter, COMBO_COL_MESH, &meshid, -1); + } + + if (valid) { + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), &iter); + } + + g_object_set_data(G_OBJECT(combo), "update", GINT_TO_POINTER(FALSE)); + } +} + +static void sp_paint_selector_set_mode_mesh(SPPaintSelector *psel, SPPaintSelector::Mode mode) +{ + if (mode == SPPaintSelector::MODE_GRADIENT_MESH) { + sp_paint_selector_set_style_buttons(psel, psel->mesh); + } + gtk_widget_set_sensitive(psel->style, TRUE); + + GtkWidget *tbl = NULL; + + if (psel->mode == SPPaintSelector::MODE_GRADIENT_MESH) { + /* Already have mesh menu */ + tbl = GTK_WIDGET(g_object_get_data(G_OBJECT(psel->selector), "mesh-selector")); + } else { + sp_paint_selector_clear_frame(psel); + + /* Create vbox */ + tbl = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); + gtk_box_set_homogeneous(GTK_BOX(tbl), FALSE); + gtk_widget_show(tbl); + + { + auto hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1); + gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); + + /** + * Create a combo_box and store with 4 columns, + * The label, a pointer to the mesh, is stockid or not, is a separator or not. + */ + GtkListStore *store = gtk_list_store_new (COMBO_N_COLS, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_BOOLEAN); + GtkWidget *combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)); + gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(combo), SPPaintSelector::isSeparator, NULL, NULL); + + GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); + gtk_cell_renderer_set_padding (renderer, 2, 0); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", COMBO_COL_LABEL, NULL); + + ink_mesh_menu(combo); + g_signal_connect(G_OBJECT(combo), "changed", G_CALLBACK(sp_psel_mesh_change), psel); + g_signal_connect(G_OBJECT(combo), "destroy", G_CALLBACK(sp_psel_mesh_destroy), psel); + g_object_set_data(G_OBJECT(psel), "meshmenu", combo); + g_object_ref( G_OBJECT(combo)); + + gtk_container_add(GTK_CONTAINER(hb), combo); + gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS); + + g_object_unref( G_OBJECT(store)); + } + + { + auto hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); + auto l = gtk_label_new(NULL); + gtk_label_set_markup(GTK_LABEL(l), _("Use the <b>Mesh tool</b> to modify the mesh.")); + gtk_label_set_line_wrap(GTK_LABEL(l), true); + gtk_widget_set_size_request(l, 180, -1); + gtk_box_pack_start(GTK_BOX(hb), l, TRUE, TRUE, AUX_BETWEEN_BUTTON_GROUPS); + gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS); + } + + gtk_widget_show_all(tbl); + + gtk_container_add(GTK_CONTAINER(psel->frame), tbl); + psel->selector = tbl; + g_object_set_data(G_OBJECT(psel->selector), "mesh-selector", tbl); + + gtk_label_set_markup(GTK_LABEL(psel->label), _("<b>Mesh fill</b>")); + } #ifdef SP_PS_VERBOSE - g_print("Gradient req\n"); + g_print("Mesh req\n"); #endif } +SPMeshGradient *SPPaintSelector::getMeshGradient() +{ + g_return_val_if_fail((mode == MODE_GRADIENT_MESH) , NULL); + + GtkWidget *combo = GTK_WIDGET(g_object_get_data(G_OBJECT(this), "meshmenu")); + + /* no mesh menu if we were just selected */ + if ( combo == NULL ) { + return NULL; + } + GtkTreeModel *store = gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); + + /* Get the selected mesh */ + GtkTreeIter iter; + if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX(combo), &iter) || + !gtk_list_store_iter_is_valid(GTK_LIST_STORE(store), &iter)) { + return NULL; + } + + gchar *meshid = NULL; + gboolean stockid = FALSE; + gchar *label = NULL; + gtk_tree_model_get (store, &iter, COMBO_COL_LABEL, &label, COMBO_COL_STOCK, &stockid, COMBO_COL_MESH, &meshid, -1); + // std::cout << " .. meshid: " << (meshid?meshid:"null") << " label: " << (label?label:"null") << std::endl; + if (meshid == NULL) { + return NULL; + } + + SPMeshGradient *mesh = 0; + if (strcmp(meshid, "none")){ + + gchar *mesh_name; + if (stockid) { + mesh_name = g_strconcat("urn:inkscape:mesh:", meshid, NULL); + } else { + mesh_name = g_strdup(meshid); + } + + SPObject *mesh_obj = get_stock_item(mesh_name); + if (mesh_obj && SP_IS_MESHGRADIENT(mesh_obj)) { + mesh = SP_MESHGRADIENT(mesh_obj); + } + g_free(mesh_name); + + } else { + std::cerr << "SPPaintSelector::getMeshGradient: Unexpected meshid value." << std::endl; + } + + return mesh; +} + +#endif +// ************************ End Mesh ************************ + static void sp_paint_selector_set_style_buttons(SPPaintSelector *psel, GtkWidget *active) { @@ -1046,21 +1351,13 @@ static void sp_paint_selector_set_mode_pattern(SPPaintSelector *psel, SPPaintSel sp_paint_selector_clear_frame(psel); /* Create vbox */ -#if GTK_CHECK_VERSION(3,0,0) tbl = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); gtk_box_set_homogeneous(GTK_BOX(tbl), FALSE); -#else - tbl = gtk_vbox_new(FALSE, 4); -#endif gtk_widget_show(tbl); { -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1); + auto hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1); gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); -#else - GtkWidget *hb = gtk_hbox_new(FALSE, 1); -#endif /** * Create a combo_box and store with 4 columns, @@ -1088,13 +1385,9 @@ static void sp_paint_selector_set_mode_pattern(SPPaintSelector *psel, SPPaintSel } { -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + auto hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); -#else - GtkWidget *hb = gtk_hbox_new(FALSE, 0); -#endif - GtkWidget *l = gtk_label_new(NULL); + auto l = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(l), _("Use the <b>Node tool</b> to adjust position, scale, and rotation of the pattern on canvas. Use <b>Object > Pattern > Objects to Pattern</b> to create a new pattern from selection.")); gtk_label_set_line_wrap(GTK_LABEL(l), true); gtk_widget_set_size_request(l, 180, -1); @@ -1262,7 +1555,7 @@ SPPaintSelector::Mode SPPaintSelector::getModeForStyle(SPStyle const & style, Fi } else if (SP_IS_RADIALGRADIENT(server)) { mode = MODE_GRADIENT_RADIAL; #ifdef WITH_MESH - } else if (SP_IS_MESH(server)) { + } else if (SP_IS_MESHGRADIENT(server)) { mode = MODE_GRADIENT_MESH; #endif } else if (SP_IS_PATTERN(server)) { diff --git a/src/widgets/paint-selector.h b/src/widgets/paint-selector.h index 23c2dd456..3302632b8 100644 --- a/src/widgets/paint-selector.h +++ b/src/widgets/paint-selector.h @@ -26,6 +26,9 @@ #include "ui/selected-color.h" class SPGradient; +#ifdef WITH_MESH +class SPMeshGradient; +#endif class SPDesktop; class SPPattern; class SPStyle; @@ -40,11 +43,7 @@ class SPStyle; * Generic paint selector widget. */ struct SPPaintSelector { -#if GTK_CHECK_VERSION(3,0,0) GtkBox vbox; -#else - GtkVBox vbox; -#endif enum Mode { MODE_EMPTY, @@ -102,7 +101,7 @@ struct SPPaintSelector { void setGradientLinear( SPGradient *vector ); void setGradientRadial( SPGradient *vector ); #ifdef WITH_MESH - void setGradientMesh(SPGradient *vector); + void setGradientMesh(SPMeshGradient *array); #endif void setSwatch( SPGradient *vector ); @@ -111,6 +110,12 @@ struct SPPaintSelector { void pushAttrsToGradient( SPGradient *gr ) const; SPGradient *getGradientVector(); + +#ifdef WITH_MESH + SPMeshGradient * getMeshGradient(); + void updateMeshList( SPMeshGradient *pat ); +#endif + SPPattern * getPattern(); void updatePatternList( SPPattern *pat ); @@ -125,16 +130,18 @@ struct SPPaintSelector { void onSelectedColorChanged(); }; -enum {COMBO_COL_LABEL=0, COMBO_COL_STOCK=1, COMBO_COL_PATTERN=2, COMBO_COL_SEP=3, COMBO_N_COLS=4}; - +enum { + COMBO_COL_LABEL = 0, + COMBO_COL_STOCK = 1, + COMBO_COL_PATTERN = 2, + COMBO_COL_MESH = COMBO_COL_PATTERN, + COMBO_COL_SEP = 3, + COMBO_N_COLS = 4 +}; /// The SPPaintSelector vtable struct SPPaintSelectorClass { -#if GTK_CHECK_VERSION(3,0,0) GtkBoxClass parent_class; -#else - GtkVBoxClass parent_class; -#endif void (* mode_changed) (SPPaintSelector *psel, SPPaintSelector::Mode mode); diff --git a/src/widgets/paintbucket-toolbar.cpp b/src/widgets/paintbucket-toolbar.cpp index eb55287c4..e2212b64f 100644 --- a/src/widgets/paintbucket-toolbar.cpp +++ b/src/widgets/paintbucket-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <glibmm/i18n.h> @@ -35,13 +35,12 @@ #include "document-undo.h" #include "widgets/ege-adjustment-action.h" #include "widgets/ege-select-one-action.h" -#include "preferences.h" #include "toolbox.h" #include "ui/icon-names.h" #include "ui/tools/flood-tool.h" #include "ui/uxmanager.h" #include "ui/widget/unit-tracker.h" -#include "util/units.h" +#include "widgets/ink-action.h" using Inkscape::UI::Widget::UnitTracker; using Inkscape::UI::UXManager; @@ -127,7 +126,7 @@ void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions iterator != channel_list.end(); ++iterator ) { GtkTreeIter iter; gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, (*iterator).c_str(), 1, count, -1 ); + gtk_list_store_set( model, &iter, 0, _((*iterator).c_str()), 1, count, -1 ); count++; } @@ -193,7 +192,7 @@ void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions iterator != gap_list.end(); ++iterator ) { GtkTreeIter iter; gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, (*iterator).c_str(), 1, count, -1 ); + gtk_list_store_set( model, &iter, 0, g_dpgettext2(NULL, "Flood autogap", (*iterator).c_str()), 1, count, -1 ); count++; } EgeSelectOneAction* act2 = ege_select_one_action_new( "AutoGapAction", _("Close gaps"), (""), NULL, GTK_TREE_MODEL(model) ); @@ -207,13 +206,14 @@ void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions /* Reset */ { - GtkAction* act = gtk_action_new( "PaintbucketResetAction", + InkAction* inky = ink_action_new( "PaintbucketResetAction", _("Defaults"), _("Reset paint bucket parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), - INKSCAPE_ICON("edit-clear")); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(paintbucket_defaults), holder ); - gtk_action_group_add_action( mainActions, act ); - gtk_action_set_sensitive( act, TRUE ); + INKSCAPE_ICON("edit-clear"), + Inkscape::ICON_SIZE_SMALL_TOOLBAR); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(paintbucket_defaults), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + gtk_action_set_sensitive( GTK_ACTION(inky), TRUE ); } } diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index 55127206c..96733cb22 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -25,19 +25,19 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <gtkmm.h> #include <glibmm/i18n.h> -#include <list> #include "pencil-toolbar.h" #include "desktop.h" #include "widgets/ege-adjustment-action.h" #include "widgets/ege-select-one-action.h" -#include "widgets/ink-action.h" -#include "preferences.h" +#include "ink-action.h" +#include "ink-radio-action.h" +#include "ink-toggle-action.h" #include "toolbox.h" #include "ui/tools-switch.h" #include "ui/icon-names.h" @@ -46,13 +46,10 @@ #include "widgets/spinbutton-events.h" #include <selection.h> #include "display/curve.h" -#include "live_effects/effect.h" #include "live_effects/lpe-simplify.h" #include "live_effects/lpe-powerstroke.h" -#include "live_effects/effect-enum.h" #include "live_effects/lpeobject.h" #include "live_effects/lpeobject-reference.h" -#include "sp-lpe-item.h" using Inkscape::UI::UXManager; using Inkscape::UI::ToolboxFactory; @@ -240,12 +237,13 @@ static void sp_pencil_tb_defaults(GtkWidget * /*widget*/, GObject *obj) static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(obj, "desktop")); - std::vector<SPItem *> selected = desktop->getSelection()->itemList(); - for (std::vector<SPItem *>::iterator it(selected.begin()); it != selected.end(); ++it){ - SPLPEItem* lpeitem = dynamic_cast<SPLPEItem*>(*it); + auto selected = desktop->getSelection()->items(); + SPLPEItem* lpeitem = NULL; + for (auto it(selected.begin()); it != selected.end(); ++it){ + lpeitem = dynamic_cast<SPLPEItem*>(*it); if (lpeitem && lpeitem->hasPathEffect()){ PathEffectList lpelist = lpeitem->getEffectList(); - std::list<Inkscape::LivePathEffect::LPEObjectReference *>::iterator i; + PathEffectList::iterator i; for (i = lpelist.begin(); i != lpelist.end(); ++i) { LivePathEffectObject *lpeobj = (*i)->lpeobject; if (lpeobj) { @@ -270,6 +268,10 @@ static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj) } } } + if (lpeitem) { + desktop->getSelection()->remove(lpeitem->getRepr()); + desktop->getSelection()->add(lpeitem->getRepr()); + } } static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tbl) @@ -285,8 +287,8 @@ static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tb gtk_adjustment_get_value(adj)); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(tbl, "desktop")); - std::vector<SPItem *> selected = desktop->getSelection()->itemList(); - for (std::vector<SPItem *>::iterator it(selected.begin()); it != selected.end(); ++it){ + auto selected = desktop->getSelection()->items(); + for (auto it(selected.begin()); it != selected.end(); ++it){ SPLPEItem* lpeitem = dynamic_cast<SPLPEItem*>(*it); if (lpeitem && lpeitem->hasPathEffect()){ Inkscape::LivePathEffect::Effect* simplify = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::SIMPLIFY); diff --git a/src/widgets/rect-toolbar.cpp b/src/widgets/rect-toolbar.cpp index bc27d003c..67947c1fd 100644 --- a/src/widgets/rect-toolbar.cpp +++ b/src/widgets/rect-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <glibmm/i18n.h> @@ -38,8 +38,6 @@ #include "widgets/ege-output-action.h" #include "widgets/ink-action.h" #include "inkscape.h" -#include "preferences.h" -#include "selection.h" #include "sp-namedview.h" #include "sp-rect.h" #include "toolbox.h" @@ -47,11 +45,9 @@ #include "ui/tools/rect-tool.h" #include "ui/uxmanager.h" #include "ui/widget/unit-tracker.h" -#include "util/units.h" #include "verbs.h" #include "widgets/widget-sizes.h" #include "xml/node-event-vector.h" -#include "xml/repr.h" using Inkscape::UI::Widget::UnitTracker; using Inkscape::UI::UXManager; @@ -106,8 +102,8 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const * bool modmade = false; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ if (SP_IS_RECT(*i)) { if (gtk_adjustment_get_value(adj) != 0) { (SP_RECT(*i)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); @@ -243,8 +239,8 @@ static void sp_rect_toolbox_selection_changed(Inkscape::Selection *selection, GO } purge_repr_listener( tbl, tbl ); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ if (SP_IS_RECT(*i)) { n_selected++; item = *i; diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index 9851b0606..2ac7447dd 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -13,7 +13,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <2geom/rect.h> @@ -29,22 +29,19 @@ #include "widgets/ege-adjustment-action.h" #include "helper/action-context.h" #include "helper/action.h" -#include "widgets/ink-action.h" +#include "ink-action.h" +#include "ink-toggle-action.h" #include "inkscape.h" #include "message-stack.h" -#include "preferences.h" #include "selection-chemistry.h" -#include "selection.h" #include "sp-item-transform.h" #include "sp-namedview.h" #include "toolbox.h" #include "ui/icon-names.h" #include "ui/widget/unit-tracker.h" -#include "util/units.h" #include "verbs.h" #include "widgets/icon.h" #include "widgets/sp-widget.h" -#include "widgets/spw-utilities.h" #include "widgets/widget-sizes.h" using Inkscape::UI::Widget::UnitTracker; @@ -257,7 +254,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, GObject *tbl) scaler = get_scale_transform_for_uniform_stroke (*bbox_geom, 0, 0, false, false, x0, y0, x1, y1); } - sp_selection_apply_affine(selection, scaler); + selection->applyAffine(scaler); DocumentUndo::maybeDone(document, actionkey, SP_VERB_CONTEXT_SELECT, _("Transform by toolbar")); @@ -415,12 +412,8 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb g_object_set_data(G_OBJECT(spw), "dtw", desktop->getCanvas()); // The vb frame holds all other widgets and is used to set sensitivity depending on selection state. -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *vb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + auto vb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(vb), FALSE); -#else - GtkWidget *vb = gtk_hbox_new(FALSE, 0); -#endif gtk_widget_show(vb); gtk_container_add(GTK_CONTAINER(spw), vb); @@ -557,14 +550,14 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb } else { g_warning("Unexpected holder type"); } - // "Transform with object" buttons { + InkToggleAction* itact = ink_toggle_action_new( "transform_stroke", _("Scale stroke width"), _("When scaling objects, scale the stroke width by the same proportion"), - INKSCAPE_ICON("transform-affect-stroke"), - Inkscape::ICON_SIZE_DECORATION ); + "transform-affect-stroke", + secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs->getBool("/options/transform/stroke", true) ); g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_stroke), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); @@ -574,8 +567,8 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb InkToggleAction* itact = ink_toggle_action_new( "transform_corners", _("Scale rounded corners"), _("When scaling rectangles, scale the radii of rounded corners"), - INKSCAPE_ICON("transform-affect-rounded-corners"), - Inkscape::ICON_SIZE_DECORATION ); + "transform-affect-rounded-corners", + secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs->getBool("/options/transform/rectcorners", true) ); g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_corners), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); @@ -585,8 +578,8 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb InkToggleAction* itact = ink_toggle_action_new( "transform_gradient", _("Move gradients"), _("Move gradients (in fill or stroke) along with the objects"), - INKSCAPE_ICON("transform-affect-gradient"), - Inkscape::ICON_SIZE_DECORATION ); + "transform-affect-gradient", + secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs->getBool("/options/transform/gradient", true) ); g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_gradient), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); @@ -596,8 +589,8 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb InkToggleAction* itact = ink_toggle_action_new( "transform_pattern", _("Move patterns"), _("Move patterns (in fill or stroke) along with the objects"), - INKSCAPE_ICON("transform-affect-pattern"), - Inkscape::ICON_SIZE_DECORATION ); + "transform-affect-pattern", + secondarySize ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs->getBool("/options/transform/pattern", true) ); g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_pattern), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); diff --git a/src/widgets/sp-attribute-widget.cpp b/src/widgets/sp-attribute-widget.cpp index fb7eb1420..cbff62b23 100644 --- a/src/widgets/sp-attribute-widget.cpp +++ b/src/widgets/sp-attribute-widget.cpp @@ -16,16 +16,7 @@ #include <glibmm/i18n.h> #include <gtkmm/entry.h> -#include <gtkmm/label.h> - -#if WITH_GTKMM_3_0 -# include <gtkmm/grid.h> -#else -# include <gtkmm/table.h> -#endif - -#include <sigc++/functors/ptr_fun.h> -#include <sigc++/adaptors/bind.h> +#include <gtkmm/grid.h> #include "sp-object.h" #include "xml/repr.h" @@ -156,11 +147,7 @@ void SPAttributeTable::set_object(SPObject *object, release_connection = object->connectRelease (sigc::bind<1>(sigc::ptr_fun(&sp_attribute_table_object_release), this)); // Create table -#if WITH_GTKMM_3_0 table = new Gtk::Grid(); -#else - table = new Gtk::Table(attributes.size(), 2, false); -#endif if (!(parent == NULL)) gtk_container_add(GTK_CONTAINER(parent), (GtkWidget*)table->gobj()); @@ -171,27 +158,17 @@ void SPAttributeTable::set_object(SPObject *object, Gtk::Label *ll = new Gtk::Label (_(labels[i].c_str())); ll->show(); ll->set_alignment (1.0, 0.5); - -#if WITH_GTKMM_3_0 ll->set_vexpand(); ll->set_margin_left(XPAD); ll->set_margin_right(XPAD); ll->set_margin_top(XPAD); ll->set_margin_bottom(XPAD); table->attach(*ll, 0, i, 1, 1); -#else - table->attach (*ll, 0, 1, i, i + 1, - Gtk::FILL, - (Gtk::EXPAND | Gtk::FILL), - XPAD, YPAD ); -#endif Gtk::Entry *ee = new Gtk::Entry(); ee->show(); const gchar *val = object->getRepr()->attribute(attributes[i].c_str()); ee->set_text (val ? val : (const gchar *) ""); - -#if WITH_GTKMM_3_0 ee->set_hexpand(); ee->set_vexpand(); ee->set_margin_left(XPAD); @@ -199,12 +176,6 @@ void SPAttributeTable::set_object(SPObject *object, ee->set_margin_top(XPAD); ee->set_margin_bottom(XPAD); table->attach(*ee, 1, i, 1, 1); -#else - table->attach (*ee, 1, 2, i, i + 1, - (Gtk::EXPAND | Gtk::FILL), - (Gtk::EXPAND | Gtk::FILL), - XPAD, YPAD ); -#endif _entries.push_back(ee); g_signal_connect ( ee->gobj(), "changed", diff --git a/src/widgets/sp-attribute-widget.h b/src/widgets/sp-attribute-widget.h index d9b972201..161bb706a 100644 --- a/src/widgets/sp-attribute-widget.h +++ b/src/widgets/sp-attribute-widget.h @@ -25,12 +25,7 @@ namespace Gtk { class Entry; - -#if WITH_GTKMM_3_0 class Grid; -#else -class Table; -#endif } namespace Inkscape { @@ -138,11 +133,7 @@ private: /** * Container widget for the dynamically created child widgets (labels and entry boxes). */ -#if WITH_GTKMM_3_0 Gtk::Grid *table; -#else - Gtk::Table *table; -#endif /** * List of attributes. diff --git a/src/widgets/sp-color-selector.cpp b/src/widgets/sp-color-selector.cpp index 93eaaee8b..159350012 100644 --- a/src/widgets/sp-color-selector.cpp +++ b/src/widgets/sp-color-selector.cpp @@ -4,7 +4,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <math.h> @@ -32,11 +32,7 @@ static guint csel_signals[LAST_SIGNAL] = {0}; double ColorSelector::_epsilon = 1e-4; -#if GTK_CHECK_VERSION(3,0,0) G_DEFINE_TYPE(SPColorSelector, sp_color_selector, GTK_TYPE_BOX); -#else -G_DEFINE_TYPE(SPColorSelector, sp_color_selector, GTK_TYPE_VBOX); -#endif void sp_color_selector_class_init( SPColorSelectorClass *klass ) { @@ -86,9 +82,7 @@ void sp_color_selector_class_init( SPColorSelectorClass *klass ) void sp_color_selector_init( SPColorSelector *csel ) { -#if GTK_CHECK_VERSION(3,0,0) gtk_orientable_set_orientation(GTK_ORIENTABLE(csel), GTK_ORIENTATION_VERTICAL); -#endif if ( csel->base ) { @@ -180,8 +174,6 @@ gfloat ColorSelector::getAlpha() const return _alpha; } -#include "svg/svg-icc-color.h" - /** Called from the outside to set the color; optionally emits signal (only when called from downstream, e.g. the RGBA value field, but not from the rest of the program) diff --git a/src/widgets/sp-color-selector.h b/src/widgets/sp-color-selector.h index 75cb79b00..14a9fccdf 100644 --- a/src/widgets/sp-color-selector.h +++ b/src/widgets/sp-color-selector.h @@ -64,21 +64,12 @@ private: #define SP_COLOR_SELECTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SP_TYPE_COLOR_SELECTOR, SPColorSelectorClass)) struct SPColorSelector { -#if GTK_CHECK_VERSION(3,0,0) GtkBox vbox; -#else - GtkVBox vbox; -#endif - ColorSelector* base; }; struct SPColorSelectorClass { -#if GTK_CHECK_VERSION(3,0,0) GtkBoxClass parent_class; -#else - GtkVBoxClass parent_class; -#endif const gchar **name; guint submode_count; diff --git a/src/widgets/sp-widget.cpp b/src/widgets/sp-widget.cpp index 5ab6b1bb5..707e62c12 100644 --- a/src/widgets/sp-widget.cpp +++ b/src/widgets/sp-widget.cpp @@ -13,7 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "macros.h" #include "document.h" #include "inkscape.h" #include "sp-widget.h" @@ -41,7 +40,6 @@ public: static void show(GtkWidget *widget); static void hide(GtkWidget *widget); -#if GTK_CHECK_VERSION(3,0,0) static void getPreferredWidth(GtkWidget *widget, gint *minimal_width, gint *natural_width); @@ -50,10 +48,6 @@ public: gint *minimal_height, gint *natural_height); static gboolean draw(GtkWidget *widget, cairo_t *cr); -#else - static void sizeRequest(GtkWidget *widget, GtkRequisition *requisition); - static gboolean expose(GtkWidget *widget, GdkEventExpose *event); -#endif static void sizeAllocate(GtkWidget *widget, GtkAllocation *allocation); static void modifySelectionCB(Selection *selection, guint flags, SPWidget *spw); @@ -120,14 +114,9 @@ sp_widget_class_init(SPWidgetClass *klass) widget_class->show = SPWidgetImpl::show; widget_class->hide = SPWidgetImpl::hide; -#if GTK_CHECK_VERSION(3,0,0) widget_class->get_preferred_width = SPWidgetImpl::getPreferredWidth; widget_class->get_preferred_height = SPWidgetImpl::getPreferredHeight; widget_class->draw = SPWidgetImpl::draw; -#else - widget_class->size_request = SPWidgetImpl::sizeRequest; - widget_class->expose_event = SPWidgetImpl::expose; -#endif widget_class->size_allocate = SPWidgetImpl::sizeAllocate; } @@ -207,27 +196,18 @@ void SPWidgetImpl::hide(GtkWidget *widget) } } -#if GTK_CHECK_VERSION(3,0,0) gboolean SPWidgetImpl::draw(GtkWidget *widget, cairo_t *cr) -#else -gboolean SPWidgetImpl::expose(GtkWidget *widget, GdkEventExpose *event) -#endif { GtkBin *bin = GTK_BIN(widget); GtkWidget *child = gtk_bin_get_child(bin); if (child) { -#if GTK_CHECK_VERSION(3,0,0) gtk_container_propagate_draw(GTK_CONTAINER(widget), child, cr); -#else - gtk_container_propagate_expose(GTK_CONTAINER(widget), child, event); -#endif } return FALSE; } -#if GTK_CHECK_VERSION(3,0,0) void SPWidgetImpl::getPreferredWidth(GtkWidget *widget, gint *minimal_width, gint *natural_width) { GtkBin *bin = GTK_BIN(widget); @@ -247,17 +227,6 @@ void SPWidgetImpl::getPreferredHeight(GtkWidget *widget, gint *minimal_height, g gtk_widget_get_preferred_height(child, minimal_height, natural_height); } } -#else -void SPWidgetImpl::sizeRequest(GtkWidget *widget, GtkRequisition *requisition) -{ - GtkBin *bin = GTK_BIN(widget); - GtkWidget *child = gtk_bin_get_child(bin); - - if (child) { - gtk_widget_size_request(child, requisition); - } -} -#endif void SPWidgetImpl::sizeAllocate(GtkWidget *widget, GtkAllocation *allocation) { diff --git a/src/widgets/sp-xmlview-attr-list.cpp b/src/widgets/sp-xmlview-attr-list.cpp index a4c00db7c..e99605b97 100644 --- a/src/widgets/sp-xmlview-attr-list.cpp +++ b/src/widgets/sp-xmlview-attr-list.cpp @@ -10,7 +10,7 @@ */ #ifdef HAVE_CONFIG_H -# include <config.h> +#include <config.h> #endif #include <cstring> @@ -20,11 +20,7 @@ #include "../xml/node-event-vector.h" #include "sp-xmlview-attr-list.h" -#if GTK_CHECK_VERSION(3,0,0) static void sp_xmlview_attr_list_destroy(GtkWidget * object); -#else -static void sp_xmlview_attr_list_destroy(GtkObject * object); -#endif static void event_attr_changed (Inkscape::XML::Node * repr, const gchar * name, const gchar * old_value, const gchar * new_value, bool is_interactive, gpointer data); @@ -87,13 +83,8 @@ G_DEFINE_TYPE(SPXMLViewAttrList, sp_xmlview_attr_list, GTK_TYPE_TREE_VIEW); void sp_xmlview_attr_list_class_init (SPXMLViewAttrListClass * klass) { -#if GTK_CHECK_VERSION(3,0,0) - GtkWidgetClass * widget_class = GTK_WIDGET_CLASS(klass); + auto widget_class = GTK_WIDGET_CLASS(klass); widget_class->destroy = sp_xmlview_attr_list_destroy; -#else - GtkObjectClass * object_class = GTK_OBJECT_CLASS(klass); - object_class->destroy = sp_xmlview_attr_list_destroy; -#endif g_signal_new("row-value-changed", G_TYPE_FROM_CLASS(klass), @@ -112,11 +103,7 @@ sp_xmlview_attr_list_init (SPXMLViewAttrList * list) list->repr = NULL; } -#if GTK_CHECK_VERSION(3,0,0) void sp_xmlview_attr_list_destroy(GtkWidget * object) -#else -void sp_xmlview_attr_list_destroy(GtkObject * object) -#endif { SPXMLViewAttrList * list; @@ -125,11 +112,7 @@ void sp_xmlview_attr_list_destroy(GtkObject * object) g_object_unref(list->store); sp_xmlview_attr_list_set_repr (list, NULL); -#if GTK_CHECK_VERSION(3,0,0) GTK_WIDGET_CLASS(sp_xmlview_attr_list_parent_class)->destroy (object); -#else - GTK_OBJECT_CLASS(sp_xmlview_attr_list_parent_class)->destroy (object); -#endif } void sp_xmlview_attr_list_select_row_by_key(SPXMLViewAttrList * list, const gchar *name) diff --git a/src/widgets/sp-xmlview-content.cpp b/src/widgets/sp-xmlview-content.cpp index a1d8475ba..6e59ba3cd 100644 --- a/src/widgets/sp-xmlview-content.cpp +++ b/src/widgets/sp-xmlview-content.cpp @@ -23,11 +23,7 @@ using Inkscape::DocumentUndo; -#if GTK_CHECK_VERSION(3,0,0) static void sp_xmlview_content_destroy(GtkWidget * object); -#else -static void sp_xmlview_content_destroy(GtkObject * object); -#endif void sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text); @@ -80,13 +76,8 @@ G_DEFINE_TYPE(SPXMLViewContent, sp_xmlview_content, GTK_TYPE_TEXT_VIEW); void sp_xmlview_content_class_init(SPXMLViewContentClass * klass) { -#if GTK_CHECK_VERSION(3,0,0) - GtkWidgetClass * widget_class = GTK_WIDGET_CLASS(klass); + auto widget_class = GTK_WIDGET_CLASS(klass); widget_class->destroy = sp_xmlview_content_destroy; -#else - GtkObjectClass * object_class = GTK_OBJECT_CLASS(klass); - object_class->destroy = sp_xmlview_content_destroy; -#endif } void @@ -96,21 +87,13 @@ sp_xmlview_content_init (SPXMLViewContent *text) text->blocked = FALSE; } -#if GTK_CHECK_VERSION(3,0,0) void sp_xmlview_content_destroy(GtkWidget * object) -#else -void sp_xmlview_content_destroy(GtkObject * object) -#endif { SPXMLViewContent * text = SP_XMLVIEW_CONTENT (object); sp_xmlview_content_set_repr (text, NULL); -#if GTK_CHECK_VERSION(3,0,0) GTK_WIDGET_CLASS (sp_xmlview_content_parent_class)->destroy (object); -#else - GTK_OBJECT_CLASS (sp_xmlview_content_parent_class)->destroy (object); -#endif } void diff --git a/src/widgets/sp-xmlview-tree.cpp b/src/widgets/sp-xmlview-tree.cpp index 5dff9adf3..3f8cc6063 100644 --- a/src/widgets/sp-xmlview-tree.cpp +++ b/src/widgets/sp-xmlview-tree.cpp @@ -10,7 +10,6 @@ */ #include <cstring> -#include <string> #include "xml/node-event-vector.h" #include "sp-xmlview-tree.h" @@ -23,11 +22,7 @@ struct NodeData { enum { STORE_TEXT_COL = 0, STORE_DATA_COL, STORE_REPR_COL, STORE_N_COLS }; -#if GTK_CHECK_VERSION(3,0,0) static void sp_xmlview_tree_destroy(GtkWidget * object); -#else -static void sp_xmlview_tree_destroy(GtkObject * object); -#endif static NodeData * node_data_new (SPXMLViewTree * tree, GtkTreeIter * node, GtkTreeRowReference *rowref, Inkscape::XML::Node * repr); @@ -121,13 +116,8 @@ G_DEFINE_TYPE(SPXMLViewTree, sp_xmlview_tree, GTK_TYPE_TREE_VIEW); void sp_xmlview_tree_class_init(SPXMLViewTreeClass * klass) { -#if GTK_CHECK_VERSION(3,0,0) - GtkWidgetClass * widget_class = GTK_WIDGET_CLASS(klass); + auto widget_class = GTK_WIDGET_CLASS(klass); widget_class->destroy = sp_xmlview_tree_destroy; -#else - GtkObjectClass * object_class = GTK_OBJECT_CLASS(klass); - object_class->destroy = sp_xmlview_tree_destroy; -#endif // Signal for when a tree drag and drop has completed g_signal_new ( "tree_move", @@ -148,22 +138,13 @@ sp_xmlview_tree_init (SPXMLViewTree * tree) tree->dndactive = FALSE; } - -#if GTK_CHECK_VERSION(3,0,0) void sp_xmlview_tree_destroy(GtkWidget * object) -#else -void sp_xmlview_tree_destroy(GtkObject * object) -#endif { SPXMLViewTree * tree = SP_XMLVIEW_TREE (object); sp_xmlview_tree_set_repr (tree, NULL); -#if GTK_CHECK_VERSION(3,0,0) GTK_WIDGET_CLASS(sp_xmlview_tree_parent_class)->destroy (object); -#else - GTK_OBJECT_CLASS(sp_xmlview_tree_parent_class)->destroy (object); -#endif } /* diff --git a/src/widgets/spinbutton-events.cpp b/src/widgets/spinbutton-events.cpp index 0280694f6..fdf88ec85 100644 --- a/src/widgets/spinbutton-events.cpp +++ b/src/widgets/spinbutton-events.cpp @@ -12,7 +12,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <gtk/gtk.h> @@ -21,7 +21,6 @@ #include "ui/tools/tool-base.h" #include "sp-widget.h" -#include "widget-sizes.h" #include "spinbutton-events.h" gboolean spinbutton_focus_in(GtkWidget *w, GdkEventKey * /*event*/, gpointer /*data*/) diff --git a/src/widgets/spiral-toolbar.cpp b/src/widgets/spiral-toolbar.cpp index 7e7398091..98d21c84d 100644 --- a/src/widgets/spiral-toolbar.cpp +++ b/src/widgets/spiral-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <glibmm/i18n.h> @@ -37,7 +37,6 @@ #include "widgets/ege-adjustment-action.h" #include "widgets/ege-output-action.h" #include "widgets/ink-action.h" -#include "preferences.h" #include "selection.h" #include "sp-spiral.h" #include "toolbox.h" @@ -46,8 +45,6 @@ #include "verbs.h" #include "widgets/spinbutton-events.h" #include "xml/node-event-vector.h" -#include "xml/node.h" -#include "xml/repr.h" using Inkscape::UI::UXManager; using Inkscape::DocumentUndo; @@ -79,8 +76,8 @@ static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustr gchar* namespaced_name = g_strconcat("sodipodi:", value_name.data(), NULL); bool modmade = false; - std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ SPItem *item = *i; if (SP_IS_SPIRAL(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -195,8 +192,8 @@ static void sp_spiral_toolbox_selection_changed(Inkscape::Selection *selection, purge_repr_listener( tbl, tbl ); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ SPItem *item = *i; if (SP_IS_SPIRAL(item)) { n_selected++; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 9e142a8db..f456bc763 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -26,7 +26,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <gtkmm.h> @@ -36,8 +36,8 @@ #include "inkscape.h" #include "widgets/ege-adjustment-action.h" #include "widgets/ege-select-one-action.h" -#include "widgets/ink-action.h" -#include "preferences.h" +#include "ink-radio-action.h" +#include "ink-toggle-action.h" #include "toolbox.h" #include "ui/dialog/clonetiler.h" #include "ui/dialog/dialog-manager.h" @@ -211,7 +211,7 @@ static void sp_toggle_pressure_scale( GtkToggleAction* act, gpointer data) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); prefs->setBool("/tools/spray/usepressurescale", active); - if(active == true){ + if(active){ prefs->setDouble("/tools/spray/scale_variation", 0); } GObject *tbl = G_OBJECT(data); @@ -238,7 +238,7 @@ static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gboolean active = gtk_toggle_action_get_active(act); prefs->setBool("/tools/spray/picker", active); - if(active == true){ + if(active){ prefs->setBool("/dialogs/clonetiler/dotrace", false); SPDesktop *dt = SP_ACTIVE_DESKTOP; if (Inkscape::UI::Dialog::CloneTiler *ct = get_clone_tiler_panel(dt)){ diff --git a/src/widgets/spw-utilities.cpp b/src/widgets/spw-utilities.cpp index 5500e1068..88a76b1ed 100644 --- a/src/widgets/spw-utilities.cpp +++ b/src/widgets/spw-utilities.cpp @@ -11,7 +11,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <cstring> @@ -19,28 +19,17 @@ #include <gtkmm/box.h> #include <gtkmm/label.h> - -#if GTK_CHECK_VERSION(3,0,0) #include <gtkmm/grid.h> -#else -#include <gtkmm/table.h> -#endif #include "selection.h" #include "spw-utilities.h" -#include <gtk/gtk.h> - /** * Creates a label widget with the given text, at the given col, row * position in the table. */ -#if GTK_CHECK_VERSION(3,0,0) Gtk::Label * spw_label(Gtk::Grid *table, const gchar *label_text, int col, int row, Gtk::Widget* target) -#else -Gtk::Label * spw_label(Gtk::Table *table, const gchar *label_text, int col, int row, Gtk::Widget* target) -#endif { Gtk::Label *label_widget = new Gtk::Label(); g_assert(label_widget != NULL); @@ -56,7 +45,6 @@ Gtk::Label * spw_label(Gtk::Table *table, const gchar *label_text, int col, int label_widget->set_alignment(1.0, 0.5); label_widget->show(); -#if GTK_CHECK_VERSION(3,0,0) label_widget->set_hexpand(); label_widget->set_halign(Gtk::ALIGN_FILL); label_widget->set_valign(Gtk::ALIGN_CENTER); @@ -70,9 +58,6 @@ Gtk::Label * spw_label(Gtk::Table *table, const gchar *label_text, int col, int #endif table->attach(*label_widget, col, row, 1, 1); -#else - table->attach(*label_widget, col, col+1, row, row+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 4, 0); -#endif return label_widget; } @@ -84,16 +69,9 @@ spw_label_old(GtkWidget *table, const gchar *label_text, int col, int row) label_widget = gtk_label_new (label_text); g_assert(label_widget != NULL); - -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_halign(label_widget, GTK_ALIGN_END); -#else - gtk_misc_set_alignment (GTK_MISC (label_widget), 1.0, 0.5); -#endif - gtk_widget_show (label_widget); -#if GTK_CHECK_VERSION(3,0,0) #if GTK_CHECK_VERSION(3,12,0) gtk_widget_set_margin_start(label_widget, 4); gtk_widget_set_margin_end(label_widget, 4); @@ -105,10 +83,6 @@ spw_label_old(GtkWidget *table, const gchar *label_text, int col, int row) gtk_widget_set_halign(label_widget, GTK_ALIGN_FILL); gtk_widget_set_valign(label_widget, GTK_ALIGN_CENTER); gtk_grid_attach(GTK_GRID(table), label_widget, col, row, 1, 1); -#else - gtk_table_attach(GTK_TABLE (table), label_widget, col, col+1, row, row+1, - (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 0); -#endif return label_widget; } @@ -117,25 +91,16 @@ spw_label_old(GtkWidget *table, const gchar *label_text, int col, int row) * Creates a horizontal layout manager with 4-pixel spacing between children * and space for 'width' columns. */ -#if GTK_CHECK_VERSION(3,0,0) Gtk::HBox * spw_hbox(Gtk::Grid * table, int width, int col, int row) -#else -Gtk::HBox * spw_hbox(Gtk::Table * table, int width, int col, int row) -#endif { /* Create a new hbox with a 4-pixel spacing between children */ Gtk::HBox *hb = new Gtk::HBox(false, 4); g_assert(hb != NULL); hb->show(); - -#if GTK_CHECK_VERSION(3,0,0) hb->set_hexpand(); hb->set_halign(Gtk::ALIGN_FILL); hb->set_valign(Gtk::ALIGN_CENTER); table->attach(*hb, col, row, width, 1); -#else - table->attach(*hb, col, col+width, row, row+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0); -#endif return hb; } @@ -177,37 +142,21 @@ spw_checkbutton(GtkWidget * dialog, GtkWidget * table, g_assert(table != NULL); GtkWidget *l = gtk_label_new (label); - -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_halign(l, GTK_ALIGN_END); -#else - gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); -#endif - gtk_widget_show (l); -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_halign(l, GTK_ALIGN_FILL); gtk_widget_set_hexpand(l, TRUE); gtk_widget_set_valign(l, GTK_ALIGN_CENTER); gtk_grid_attach(GTK_GRID(table), l, 0, row, 1, 1); -#else - gtk_table_attach (GTK_TABLE (table), l, 0, 1, row, row+1, - (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0); -#endif b = gtk_check_button_new (); gtk_widget_show (b); -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_halign(b, GTK_ALIGN_FILL); gtk_widget_set_hexpand(b, TRUE); gtk_widget_set_valign(b, GTK_ALIGN_CENTER); gtk_grid_attach(GTK_GRID(table), b, 1, row, 1, 1); -#else - gtk_table_attach (GTK_TABLE (table), b, 1, 2, row, row+1, - (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0); -#endif g_object_set_data (G_OBJECT (b), "key", key); g_object_set_data (G_OBJECT (dialog), key, b); @@ -235,16 +184,10 @@ spw_dropdown(GtkWidget * dialog, GtkWidget * table, spw_label_old(table, label_text, 0, row); gtk_widget_show (selector); - -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_halign(selector, GTK_ALIGN_FILL); gtk_widget_set_hexpand(selector, TRUE); gtk_widget_set_valign(selector, GTK_ALIGN_CENTER); gtk_grid_attach(GTK_GRID(table), selector, 1, row, 1, 1); -#else - gtk_table_attach (GTK_TABLE (table), selector, 1, 2, row, row+1, - (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0); -#endif g_object_set_data (G_OBJECT (dialog), key, selector); return selector; @@ -255,8 +198,7 @@ sp_set_font_size_recursive (GtkWidget *w, gpointer font) { guint size = GPOINTER_TO_UINT (font); -#if GTK_CHECK_VERSION(3,0,0) - GtkCssProvider *css_provider = gtk_css_provider_new(); + auto css_provider = gtk_css_provider_new(); const double pt_size = size / static_cast<double>(PANGO_SCALE); std::ostringstream css_data; @@ -268,25 +210,16 @@ sp_set_font_size_recursive (GtkWidget *w, gpointer font) css_data.str().c_str(), -1, NULL); - GtkStyleContext *style_context = gtk_widget_get_style_context(w); + auto style_context = gtk_widget_get_style_context(w); gtk_style_context_add_provider(style_context, GTK_STYLE_PROVIDER(css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER); -#else - PangoFontDescription* pan = pango_font_description_new (); - pango_font_description_set_size (pan, size); - gtk_widget_modify_font (w, pan); -#endif if (GTK_IS_CONTAINER(w)) { gtk_container_foreach (GTK_CONTAINER(w), (GtkCallback) sp_set_font_size_recursive, font); } -#if GTK_CHECK_VERSION(3,0,0) g_object_unref(css_provider); -#else - pango_font_description_free (pan); -#endif } void diff --git a/src/widgets/spw-utilities.h b/src/widgets/spw-utilities.h index 31f29e026..71b451631 100644 --- a/src/widgets/spw-utilities.h +++ b/src/widgets/spw-utilities.h @@ -20,25 +20,13 @@ namespace Gtk { class Label; - -#if GTK_CHECK_VERSION(3,0,0) class Grid; -#else - class Table; -#endif - class HBox; class Widget; } -#if GTK_CHECK_VERSION(3,0,0) Gtk::Label * spw_label(Gtk::Grid *table, gchar const *label_text, int col, int row, Gtk::Widget *target); Gtk::HBox * spw_hbox(Gtk::Grid *table, int width, int col, int row); -#else -Gtk::Label * spw_label(Gtk::Table *table, gchar const *label_text, int col, int row, Gtk::Widget *target); -Gtk::HBox * spw_hbox(Gtk::Table *table, int width, int col, int row); -#endif - GtkWidget * spw_label_old(GtkWidget *table, gchar const *label_text, int col, int row); GtkWidget * diff --git a/src/widgets/star-toolbar.cpp b/src/widgets/star-toolbar.cpp index 982a3c854..8f667a656 100644 --- a/src/widgets/star-toolbar.cpp +++ b/src/widgets/star-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include <glibmm/i18n.h> @@ -37,7 +37,8 @@ #include "widgets/ege-adjustment-action.h" #include "widgets/ege-output-action.h" #include "widgets/ege-select-one-action.h" -#include "widgets/ink-action.h" +#include "ink-action.h" +#include "ink-radio-action.h" #include "selection.h" #include "sp-star.h" #include "toolbox.h" @@ -45,10 +46,7 @@ #include "ui/tools/star-tool.h" #include "ui/uxmanager.h" #include "verbs.h" -#include "widgets/../preferences.h" #include "xml/node-event-vector.h" -#include "xml/node.h" -#include "xml/repr.h" using Inkscape::UI::UXManager; using Inkscape::DocumentUndo; @@ -83,8 +81,8 @@ static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKlu bool modmade = false; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -128,8 +126,8 @@ static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKl bool modmade = false; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -185,8 +183,8 @@ static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *d gtk_action_set_visible( prop_action, !flat ); } - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -224,8 +222,8 @@ static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludg bool modmade = false; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -264,8 +262,8 @@ static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKl bool modmade = false; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -367,8 +365,8 @@ sp_star_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) purge_repr_listener( tbl, tbl ); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { n_selected++; diff --git a/src/widgets/stroke-marker-selector.cpp b/src/widgets/stroke-marker-selector.cpp index e273faad7..3f81bef5c 100644 --- a/src/widgets/stroke-marker-selector.cpp +++ b/src/widgets/stroke-marker-selector.cpp @@ -18,17 +18,13 @@ #include "stroke-marker-selector.h" -#include <cstring> -#include <string> #include <glibmm/i18n.h> -#include <2geom/coord.h> #include "style.h" #include "ui/dialog-events.h" #include "desktop-style.h" -#include "preferences.h" #include "path-prefix.h" #include "io/sys.h" #include "sp-marker.h" @@ -39,10 +35,8 @@ #include "gradient-vector.h" #include <gtkmm/icontheme.h> -#include <gtkmm/adjustment.h> #include "ui/widget/spinbutton.h" #include "stroke-style.h" -#include "gradient-chemistry.h" static Inkscape::UI::Cache::SvgPreview svg_preview_cache; @@ -60,8 +54,13 @@ MarkerComboBox::MarkerComboBox(gchar const *id, int l) : set_cell_data_func(image_renderer, sigc::mem_fun(*this, &MarkerComboBox::prepareImageRenderer)); gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(gobj()), MarkerComboBox::separator_cb, NULL, NULL); + Glib::ustring no_marker("no-marker"); + Glib::RefPtr<Gtk::IconTheme> iconTheme = Gtk::IconTheme::get_default(); + if (!iconTheme->has_icon(no_marker)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(no_marker.data()), Inkscape::ICON_SIZE_SMALL_TOOLBAR ); + } empty_image = new Gtk::Image( Glib::wrap( - sp_pixbuf_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("no-marker") ) ) ); + sp_pixbuf_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON(no_marker.data()) ) ) ); sandbox = ink_markers_preview_doc (); desktop = SP_ACTIVE_DESKTOP; @@ -77,6 +76,7 @@ MarkerComboBox::MarkerComboBox(gchar const *id, int l) : MarkerComboBox::~MarkerComboBox() { delete combo_id; delete sandbox; + delete empty_image; if (doc) { modified_connection.disconnect(); @@ -335,10 +335,10 @@ GSList *MarkerComboBox::get_marker_list (SPDocument *source) return NULL; } - for ( SPObject *child = defs->firstChild(); child; child = child->getNext() ) + for (auto& child: defs->children) { - if (SP_IS_MARKER(child)) { - ml = g_slist_prepend (ml, child); + if (SP_IS_MARKER(&child)) { + ml = g_slist_prepend (ml, &child); } } return ml; @@ -399,7 +399,7 @@ void MarkerComboBox::add_markers (GSList *marker_list, SPDocument *source, gbool gchar const *markid = repr->attribute("inkscape:stockid") ? repr->attribute("inkscape:stockid") : repr->attribute("id"); // generate preview - Gtk::Image *prv = create_marker_image (22, repr->attribute("id"), source, drawing, visionkey); + Gtk::Image *prv = create_marker_image (24, repr->attribute("id"), source, drawing, visionkey); prv->show(); // Add history before separator, others after @@ -430,14 +430,14 @@ void MarkerComboBox::update_marker_image(gchar const *mname) { gchar *cache_name = g_strconcat(combo_id, mname, NULL); - Glib::ustring key = svg_preview_cache.cache_key(doc->getURI(), cache_name, 22); + Glib::ustring key = svg_preview_cache.cache_key(doc->getURI(), cache_name, 24); g_free (cache_name); svg_preview_cache.remove_preview_from_cache(key); Inkscape::Drawing drawing; unsigned const visionkey = SPItem::display_key_new(1); drawing.setRoot(sandbox->getRoot()->invoke_show(drawing, visionkey, SP_ITEM_SHOW_DISPLAY)); - Gtk::Image *prv = create_marker_image(22, mname, doc, drawing, visionkey); + Gtk::Image *prv = create_marker_image(24, mname, doc, drawing, visionkey); if (prv) { prv->show(); } diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 84a6e77ad..de3e98297 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -18,13 +18,11 @@ #define noSP_SS_VERBOSE #include "stroke-style.h" -#include "gradient-chemistry.h" -#include "sp-gradient.h" #include "sp-stop.h" #include "svg/svg-color.h" -#include "util/units.h" #include "ui/widget/unit-menu.h" #include "desktop-widget.h" +#include "widgets/style-utils.h" using Inkscape::DocumentUndo; using Inkscape::Util::unit_table; @@ -155,17 +153,9 @@ StrokeStyle::StrokeStyle() : Gtk::HBox *f = new Gtk::HBox(false, 0); f->show(); add(*f); - -#if WITH_GTKMM_3_0 table = new Gtk::Grid(); table->set_border_width(4); table->set_row_spacing(4); -#else - table = new Gtk::Table(3, 6, false); - table->set_border_width(4); - table->set_row_spacings(4); -#endif - table->show(); f->add(*table); @@ -181,13 +171,7 @@ StrokeStyle::StrokeStyle() : // stroke_width_set_unit will be removed (because ScalarUnit takes care of conversions itself), and // with it, the two remaining calls of stroke_average_width, allowing us to get rid of that // function in desktop-style. - -#if WITH_GTKMM_3_0 widthAdj = new Glib::RefPtr<Gtk::Adjustment>(Gtk::Adjustment::create(1.0, 0.0, 1000.0, 0.1, 10.0, 0.0)); -#else - widthAdj = new Gtk::Adjustment(1.0, 0.0, 1000.0, 0.1, 10.0, 0.0); -#endif - widthSpin = new Inkscape::UI::Widget::SpinButton(*widthAdj, 0.1, 3); widthSpin->set_tooltip_text(_("Stroke width")); widthSpin->show(); @@ -213,12 +197,7 @@ StrokeStyle::StrokeStyle() : us->show(); hb->pack_start(*us, FALSE, FALSE, 0); - -#if WITH_GTKMM_3_0 (*widthAdj)->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::widthChangedCB)); -#else - widthAdj->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::widthChangedCB)); -#endif i++; /* Dash */ @@ -230,16 +209,10 @@ StrokeStyle::StrokeStyle() : dashSelector = Gtk::manage(new SPDashSelector); dashSelector->show(); - -#if WITH_GTKMM_3_0 dashSelector->set_hexpand(); dashSelector->set_halign(Gtk::ALIGN_FILL); dashSelector->set_valign(Gtk::ALIGN_CENTER); table->attach(*dashSelector, 1, i, 3, 1); -#else - table->attach(*dashSelector, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0); -#endif - dashSelector->changed_signal.connect(sigc::mem_fun(*this, &StrokeStyle::lineDashChangedCB)); i++; @@ -323,28 +296,14 @@ StrokeStyle::StrokeStyle() : // miter limit is to cut off such spikes (i.e. convert them into bevels) // when they become too long. //spw_label(t, _("Miter _limit:"), 0, i); - -#if WITH_GTKMM_3_0 miterLimitAdj = new Glib::RefPtr<Gtk::Adjustment>(Gtk::Adjustment::create(4.0, 0.0, 100.0, 0.1, 10.0, 0.0)); miterLimitSpin = new Inkscape::UI::Widget::SpinButton(*miterLimitAdj, 0.1, 2); -#else - miterLimitAdj = new Gtk::Adjustment(4.0, 0.0, 100.0, 0.1, 10.0, 0.0); - miterLimitSpin = new Inkscape::UI::Widget::SpinButton(*miterLimitAdj, 0.1, 2); -#endif - miterLimitSpin->set_tooltip_text(_("Maximum length of the miter (in units of stroke width)")); miterLimitSpin->show(); sp_dialog_defocus_on_enter_cpp(miterLimitSpin); hb->pack_start(*miterLimitSpin, false, false, 0); - -#if WITH_GTKMM_3_0 (*miterLimitAdj)->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::miterLimitChangedCB)); - -#else - miterLimitAdj->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::miterLimitChangedCB)); -#endif - i++; /* Cap type */ @@ -479,6 +438,12 @@ StrokeStyle::makeRadioButton(Gtk::RadioButtonGroup &grp, return tb; } +bool StrokeStyle::shouldMarkersBeUpdated() +{ + return startMarkerCombo->update() || midMarkerCombo->update() || + endMarkerCombo->update(); +} + /** * Handles when user selects one of the markers from the marker combobox. * Gets the marker uri string and applies it to all selected @@ -486,11 +451,7 @@ StrokeStyle::makeRadioButton(Gtk::RadioButtonGroup &grp, */ void StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMarkerLoc const /*which*/) { - bool markers_update = spw->startMarkerCombo->update() || - spw->midMarkerCombo->update() || - spw->endMarkerCombo->update(); - - if (spw->update || markers_update) { + if (spw->update || spw->shouldMarkersBeUpdated()) { return; } @@ -515,8 +476,8 @@ void StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, //spw->updateMarkerHist(which); Inkscape::Selection *selection = spw->desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (!SP_IS_SHAPE(item) || SP_IS_RECT(item)) { // can't set marker to rect, until it's converted to using <path> continue; @@ -927,17 +888,9 @@ StrokeStyle::updateLine() if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { double avgwidth = Inkscape::Util::Quantity::convert(query.stroke_width.computed, "px", unit); -#if WITH_GTKMM_3_0 (*widthAdj)->set_value(avgwidth); -#else - widthAdj->set_value(avgwidth); -#endif } else { -#if WITH_GTKMM_3_0 (*widthAdj)->set_value(100); -#else - widthAdj->set_value(100); -#endif } // if none of the selected objects has a stroke, than quite some controls should be disabled @@ -958,28 +911,22 @@ StrokeStyle::updateLine() } if (result_ml != QUERY_STYLE_NOTHING) -#if WITH_GTKMM_3_0 (*miterLimitAdj)->set_value(query.stroke_miterlimit.value); // TODO: reflect averagedness? -#else - miterLimitAdj->set_value(query.stroke_miterlimit.value); // TODO: reflect averagedness? -#endif - if (result_join != QUERY_STYLE_MULTIPLE_DIFFERENT && - result_join != QUERY_STYLE_NOTHING ) { + using Inkscape::is_query_style_updateable; + if (! is_query_style_updateable(result_join)) { setJoinType(query.stroke_linejoin.value); } else { setJoinButtons(NULL); } - if (result_cap != QUERY_STYLE_MULTIPLE_DIFFERENT && - result_cap != QUERY_STYLE_NOTHING ) { + if (! is_query_style_updateable(result_cap)) { setCapType (query.stroke_linecap.value); } else { setCapButtons(NULL); } - if (result_order != QUERY_STYLE_MULTIPLE_DIFFERENT && - result_order != QUERY_STYLE_NOTHING ) { + if (! is_query_style_updateable(result_order)) { setPaintOrder (query.paint_order.value); } else { setPaintOrder (NULL); @@ -988,12 +935,12 @@ StrokeStyle::updateLine() if (!sel || sel->isEmpty()) return; - std::vector<SPItem*> const objects = sel->itemList(); + std::vector<SPItem*> const objects(sel->items().begin(), sel->items().end()); SPObject * const object = objects[0]; SPStyle * const style = object->style; /* Markers */ - updateAllMarkers(objects); // FIXME: make this desktop query too + updateAllMarkers(objects, true); // FIXME: make this desktop query too /* Dash */ setDashSelectorFromStyle(dashSelector, style); // FIXME: make this desktop query too @@ -1030,6 +977,16 @@ StrokeStyle::setScaledDash(SPCSSAttr *css, } } +static inline double calcScaleLineWidth(const double width_typed, SPItem *const item, Inkscape::Util::Unit const *const unit) +{ + if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { + return Inkscape::Util::Quantity::convert(width_typed, unit, "px"); + } else { // percentage + const gdouble old_w = item->style->stroke_width.computed; + return old_w * width_typed / 100; + } +} + /** * Sets line properties like width, dashes, markers, etc. on all currently selected items. */ @@ -1044,19 +1001,14 @@ StrokeStyle::scaleLine() SPDocument *document = desktop->getDocument(); Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> items=selection->itemList(); + auto items= selection->items(); /* TODO: Create some standardized method */ SPCSSAttr *css = sp_repr_css_attr_new(); if (!items.empty()) { -#if WITH_GTKMM_3_0 double width_typed = (*widthAdj)->get_value(); double const miterlimit = (*miterLimitAdj)->get_value(); -#else - double width_typed = widthAdj->get_value(); - double const miterlimit = miterLimitAdj->get_value(); -#endif Inkscape::Util::Unit const *const unit = unitSelector->getUnit(); @@ -1064,15 +1016,9 @@ StrokeStyle::scaleLine() int ndash; dashSelector->get_dash(&ndash, &dash, &offset); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + for(auto i=items.begin();i!=items.end();++i){ /* Set stroke width */ - double width; - if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { - width = Inkscape::Util::Quantity::convert(width_typed, unit, "px"); - } else { // percentage - gdouble old_w = (*i)->style->stroke_width.computed; - width = old_w * width_typed / 100; - } + const double width = calcScaleLineWidth(width_typed, (*i), unit); { Inkscape::CSSOStringStream os_width; @@ -1096,11 +1042,7 @@ StrokeStyle::scaleLine() if (unit->type != Inkscape::Util::UNIT_TYPE_LINEAR) { // reset to 100 percent -#if WITH_GTKMM_3_0 (*widthAdj)->set_value(100.0); -#else - widthAdj->set_value(100.0); -#endif } } @@ -1250,7 +1192,7 @@ StrokeStyle::setPaintOrderButtons(Gtk::ToggleButton *active) * that marker. */ void -StrokeStyle::updateAllMarkers(std::vector<SPItem*> const &objects) +StrokeStyle::updateAllMarkers(std::vector<SPItem*> const &objects, bool skip_undo) { struct { MarkerComboBox *key; int loc; } const keyloc[] = { { startMarkerCombo, SP_MARKER_LOC_START }, @@ -1304,9 +1246,11 @@ StrokeStyle::updateAllMarkers(std::vector<SPItem*> const &objects) if (update) { setMarkerColor(marker, combo->get_loc(), SP_ITEM(object)); - SPDocument *document = desktop->getDocument(); - DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, + if (!skip_undo) { + SPDocument *document = desktop->getDocument(); + DocumentUndo::maybeDone(document, "UaM", SP_VERB_DIALOG_FILL_STROKE, _("Set marker color")); + } } } else { diff --git a/src/widgets/stroke-style.h b/src/widgets/stroke-style.h index d83067a4a..cdd825c7d 100644 --- a/src/widgets/stroke-style.h +++ b/src/widgets/stroke-style.h @@ -23,12 +23,7 @@ #include "widgets/dash-selector.h" #include <gtkmm/radiobutton.h> - -#if WITH_GTKMM_3_0 #include <gtkmm/grid.h> -#else -#include <gtkmm/table.h> -#endif #include <glibmm/i18n.h> @@ -154,7 +149,7 @@ private: }; void updateLine(); - void updateAllMarkers(std::vector<SPItem*> const &objects); + void updateAllMarkers(std::vector<SPItem*> const &objects, bool skip_undo = false); void updateMarkerHist(SPMarkerLoc const which); void setDashSelectorFromStyle(SPDashSelector *dsel, SPStyle *style); void setJoinType (unsigned const jointype); @@ -182,6 +177,7 @@ private: void miterLimitChangedCB(); void lineDashChangedCB(); void unitChangedCB(); + bool shouldMarkersBeUpdated(); static void markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMarkerLoc const which); static void buttonToggledCB(StrokeStyleButton *tb, StrokeStyle *spw); @@ -189,15 +185,9 @@ private: MarkerComboBox *startMarkerCombo; MarkerComboBox *midMarkerCombo; MarkerComboBox *endMarkerCombo; -#if WITH_GTKMM_3_0 Gtk::Grid *table; Glib::RefPtr<Gtk::Adjustment> *widthAdj; Glib::RefPtr<Gtk::Adjustment> *miterLimitAdj; -#else - Gtk::Table *table; - Gtk::Adjustment *widthAdj; - Gtk::Adjustment *miterLimitAdj; -#endif Inkscape::UI::Widget::SpinButton *miterLimitSpin; Inkscape::UI::Widget::SpinButton *widthSpin; Inkscape::UI::Widget::UnitMenu *unitSelector; diff --git a/src/widgets/style-utils.h b/src/widgets/style-utils.h new file mode 100644 index 000000000..65b635f0c --- /dev/null +++ b/src/widgets/style-utils.h @@ -0,0 +1,45 @@ +/** + * @file + * Common utility functions for manipulating style. + */ +/* Author: + * Shlomi Fish <shlomif@cpan.org> + * + * Copyright (C) 2016 Shlomi Fish + * + * Dually-Licensed under: + * + * 1. The Expat license - https://www.gnu.org/licenses/license-list.html#Expat + * + * 2. The GNU General Public License, either version 2, or at your option, + * any later version of it. + * ( https://en.wikipedia.org/wiki/GNU_General_Public_License ) + */ + +#ifndef SEEN_DIALOGS_STYLE_UTILS_H +#define SEEN_DIALOGS_STYLE_UTILS_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "desktop-style.h" + +namespace Inkscape { + inline bool is_query_style_updateable(const int style) { + return (style == QUERY_STYLE_MULTIPLE_DIFFERENT || style == QUERY_STYLE_NOTHING); + } +} // namespace Inkscape + +#endif // SEEN_DIALOGS_STYLE_UTILS_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 23acb74af..efa5527e4 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include <config.h> #endif #include "libnrtype/font-lister.h" @@ -38,12 +38,12 @@ #include "document.h" #include "widgets/ege-adjustment-action.h" #include "widgets/ege-select-one-action.h" -#include "widgets/ink-action.h" +#include "ink-radio-action.h" +#include "ink-toggle-action.h" #include "widgets/ink-comboboxentry-action.h" +#include "widgets/style-utils.h" #include "inkscape.h" -#include "preferences.h" #include "selection-chemistry.h" -#include "selection.h" #include "sp-flowtext.h" #include "sp-root.h" #include "sp-text.h" @@ -53,11 +53,8 @@ #include "toolbox.h" #include "ui/icon-names.h" #include "ui/tools/text-tool.h" -#include "ui/tools/tool-base.h" #include "ui/widget/unit-tracker.h" -#include "util/units.h" #include "verbs.h" -#include "xml/repr.h" using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; @@ -120,6 +117,8 @@ static void sp_print_fontstyle( SPStyle *query ) { } #endif +static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection = false); + // Font family static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) { @@ -206,6 +205,7 @@ static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObje if (endptr == text) { // Conversion failed, non-numeric input. g_warning( "Conversion of size text to double failed, input: %s\n", text ); g_free( text ); + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); return; } g_free( text ); @@ -228,8 +228,35 @@ static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObje sp_repr_css_set_property (css, "font-size", osfs.str().c_str()); // Apply font size to selected objects. + // Calling sp_desktop_set_style will result in a call to TextTool::_styleSet() which + // will set the style on selected text inside the <text> element. If we want to set + // the style on the outer <text> objects we need to bypass this call. + bool outer = prefs->getInt("/tools/text/outer_style", false); SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, true); + if (outer) { + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (dynamic_cast<SPText *>(*i) || dynamic_cast<SPFlowtext *>(*i)) { + SPItem *item = *i; + + // Scale by inverse of accumulated parent transform + SPCSSAttr *css_set = sp_repr_css_attr_new(); + sp_repr_css_merge(css_set, css); + Geom::Affine const local(item->i2doc_affine()); + double const ex(local.descrim()); + if ( (ex != 0.0) && (ex != 1.0) ) { + sp_css_attr_scale(css_set, 1/ex); + } + + item->changeCSS(css_set,"style"); + + sp_repr_css_attr_unref(css_set); + } + } + } else { + sp_desktop_set_style (desktop, css, true, true); + } // If no selected objects, set default. SPStyle query(SP_ACTIVE_DOCUMENT); @@ -275,15 +302,62 @@ static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObj SPDesktop *desktop = SP_ACTIVE_DESKTOP; sp_desktop_set_style (desktop, css, true, true); + + + // If no selected objects, set default. + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_style = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); + if (result_style == QUERY_STYLE_NOTHING) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } else { + // Save for undo + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, + _("Text: Change font style")); + } + sp_repr_css_attr_unref (css); - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, - _("Text: Change font style")); } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } +// Changes selection to only text outer elements. +static void sp_text_outer_style_changed( InkToggleAction*act, GObject *tbl ) +{ + bool outer = gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(act) ); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/tools/text/outer_style", outer); + + // Update widgets to reflect new state of Text Outer Style button. + sp_text_toolbox_selection_changed( NULL, tbl ); +} + +// Unset line height on selection's inner text objects (tspan, etc.). +static void sp_text_lineheight_unset_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) ); + + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_unset_property(css, "line-height"); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css); + + sp_repr_css_attr_unref(css); + + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, + _("Text: Unset line height.")); + + 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 ) { @@ -308,7 +382,7 @@ static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) bool setSuper = false; bool setSub = false; - if(result_baseline == QUERY_STYLE_NOTHING || result_baseline == QUERY_STYLE_MULTIPLE_DIFFERENT ) { + if (Inkscape::is_query_style_updateable(result_baseline)) { // If not set or mixed, turn on superscript or subscript if( prop == 0 ) { setSuper = true; @@ -378,8 +452,8 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) // move the x of all texts to preserve the same bbox Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ if (SP_IS_TEXT(*i)) { SPItem *item = *i; @@ -511,7 +585,7 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) static bool is_relative( Unit const *unit ) { return (unit->abbr == "" || unit->abbr == "em" || unit->abbr == "ex" || unit->abbr == "%"); } - + static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) { // quit if run by the _changed callbacks @@ -528,17 +602,14 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - // Only save if not relative unit - if ( !is_relative(unit) ) { - // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit so - // we can save it (allows us to adjust line height value when unit changes). - SPILength temp_length; - Inkscape::CSSOStringStream temp_stream; - temp_stream << 1 << unit->abbr; - temp_length.read(temp_stream.str().c_str()); - prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); - g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); - } + // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit so + // we can save it (allows us to adjust line height value when unit changes). + SPILength temp_length; + Inkscape::CSSOStringStream temp_stream; + temp_stream << 1 << unit->abbr; + temp_length.read(temp_stream.str().c_str()); + prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); + g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); // Set css line height. SPCSSAttr *css = sp_repr_css_attr_new (); @@ -552,16 +623,41 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); - // Apply line-height to selected objects. + // Apply line-height to selected objects. See comment in font size function. + bool outer = prefs->getInt("/tools/text/outer_style", false); SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, false); + if (outer) { + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (dynamic_cast<SPText *>(*i) || dynamic_cast<SPFlowtext *>(*i)) { + SPItem *item = *i; + + // Scale by inverse of accumulated parent transform + SPCSSAttr *css_set = sp_repr_css_attr_new(); + sp_repr_css_merge(css_set, css); + Geom::Affine const local(item->i2doc_affine()); + double const ex(local.descrim()); + if ( (ex != 0.0) && (ex != 1.0) ) { + sp_css_attr_scale(css_set, 1/ex); + } + + item->changeCSS(css_set,"style"); + + sp_repr_css_attr_unref(css_set); + } + } + } else { + sp_desktop_set_style (desktop, css, true, true); + } + // Only need to save for undo if a text item has been changed. Inkscape::Selection *selection = desktop->getSelection(); bool modmade = false; - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ if (SP_IS_TEXT (*i)) { modmade = true; } @@ -569,6 +665,16 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) // Save for undo if(modmade) { + // Call ensureUpToDate() causes rebuild of text layout (with all proper style + // cascading, etc.). For multi-line text with sodipodi::role="line", we must explicitly + // save new <tspan> 'x' and 'y' attribute values by calling updateRepr(). + // Partial fix for bug #1590141. + desktop->getDocument()->ensureUpToDate(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (SP_IS_TEXT (*i)) { + (*i)->updateRepr(); + } + } DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:line-height", SP_VERB_NONE, _("Text: Change line-height")); } @@ -606,16 +712,13 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) g_return_if_fail(unit != NULL); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - // Only save if not relative unit - if ( !is_relative(unit) ) { - // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit. - SPILength temp_length; - Inkscape::CSSOStringStream temp_stream; - temp_stream << 1 << unit->abbr; - temp_length.read(temp_stream.str().c_str()); - prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); - g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); - } + // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit. + SPILength temp_length; + Inkscape::CSSOStringStream temp_stream; + temp_stream << 1 << unit->abbr; + temp_length.read(temp_stream.str().c_str()); + prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); + g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); // Read current line height value EgeAdjustmentAction *line_height_act = @@ -625,10 +728,13 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) SPDesktop *desktop = SP_ACTIVE_DESKTOP; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); + auto itemlist = selection->items(); // Convert between units - if ((unit->abbr == "" || unit->abbr == "em") && old_unit == SP_CSS_UNIT_EX) { + if ((unit->abbr == "" || unit->abbr == "em") && + (old_unit == SP_CSS_UNIT_NONE || old_unit == SP_CSS_UNIT_EM)) { + // Do nothing + } else if ((unit->abbr == "" || unit->abbr == "em") && old_unit == SP_CSS_UNIT_EX) { line_height *= 0.5; } else if ((unit->abbr) == "ex" && (old_unit == SP_CSS_UNIT_EM || old_unit == SP_CSS_UNIT_NONE) ) { line_height *= 2.0; @@ -644,8 +750,8 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) // Convert absolute to relative... for the moment use average font-size double font_size = 0; int count = 0; - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ - if (SP_IS_TEXT (*i)) { + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (SP_IS_TEXT (*i) || SP_IS_FLOWTEXT(*i)) { double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); font_size += (*i)->style->font_size.computed * doc_scale; ++count; @@ -673,8 +779,8 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) // Convert relative to absolute... for the moment use average font-size double font_size = 0; int count = 0; - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ - if (SP_IS_TEXT (*i)) { + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (SP_IS_TEXT (*i) || SP_IS_FLOWTEXT (*i)) { double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); font_size += (*i)->style->font_size.computed * doc_scale; ++count; @@ -716,7 +822,7 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) // Only need to save for undo if a text item has been changed. bool modmade = false; - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ if (SP_IS_TEXT (*i)) { modmade = true; } @@ -1035,6 +1141,54 @@ static void sp_text_orientation_changed( EgeSelectOneAction *act, GObject *tbl ) g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } +static void sp_text_direction_changed( EgeSelectOneAction *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) ); + + int mode = ege_select_one_action_get_active( act ); + + SPCSSAttr *css = sp_repr_css_attr_new (); + switch (mode) + { + case 0: + { + sp_repr_css_set_property (css, "direction", "ltr"); + break; + } + + case 1: + { + sp_repr_css_set_property (css, "direction", "rtl"); + break; + } + } + + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + + // If querying returned nothing, update default style. + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } + + sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); + if(result_numbers != QUERY_STYLE_NOTHING) + { + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, + _("Text: Change direction")); + } + sp_repr_css_attr_unref (css); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + /* * Set the default list of font sizes, scaled to the users preferred unit */ @@ -1066,7 +1220,7 @@ static void sp_text_set_sizes(GtkListStore* model_size, int unit) * It is called whenever a text selection is changed, including stepping cursor * through text, or setting focus to text. */ -static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection = false) // don't bother to update font list if subsel changed +static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection) // don't bother to update font list if subsel changed { #ifdef DEBUG_TEXT static int count = 0; @@ -1075,12 +1229,10 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; std::cout << "sp_text_toolbox_selection_changed: start " << count << std::endl; - std::cout << " Selected items:" << std::endl; - for (GSList const *items = SP_ACTIVE_DESKTOP->getSelection()->itemList(); - items != NULL; - items = items->next) - { - const gchar* id = reinterpret_cast<SPItem *>(items->data)->getId(); + Inkscape::Selection *selection = (SP_ACTIVE_DESKTOP)->getSelection(); + auto itemlist0= selection->items(); + for(auto i=itemlist0.begin();i!=itemlist0.end(); ++i) { + const gchar* id = (*i)->getId(); std::cout << " " << id << std::endl; } Glib::ustring selected_text = sp_text_get_selected_text((SP_ACTIVE_DESKTOP)->event_context); @@ -1120,10 +1272,9 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // 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; - std::vector<SPItem*> itemlist=SP_ACTIVE_DESKTOP->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ - // const gchar* id = reinterpret_cast<SPItem *>(items->data)->getId(); - // std::cout << " " << id << std::endl; + auto itemlist= SP_ACTIVE_DESKTOP->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + // std::cout << " " << ((*i)->getId()?(*i)->getId():"null") << std::endl; if( SP_IS_FLOWTEXT(*i)) { isFlow = true; // std::cout << " Found flowed text" << std::endl; @@ -1141,10 +1292,26 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ SPStyle query(SP_ACTIVE_DOCUMENT); 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); int result_wmode = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_WRITINGMODES); + // Calling sp_desktop_query_style will result in a call to TextTool::_styleQueried(). + // This returns the style of the selected text inside the <text> element... which + // is often the style of one or more <tspan>s. If we want the style of the outer + // <text> objects then we need to bypass the call to TextTool::_styleQueried(). + // The desktop selection never includes the elements inside the <text> element. + int result_numbers = 0; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + bool outer = prefs->getInt("/tools/text/outer_style", false); + if (outer) { + Inkscape::Selection *selection = desktop->getSelection(); + std::vector<SPItem *> vec(selection->items().begin(), selection->items().end()); + result_numbers = sp_desktop_query_style_from_list (vec, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + } else { + result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + } + /* * If no text in selection (querying returned nothing), read the style from * the /tools/text preferencess (default style for new texts). Return if @@ -1319,7 +1486,13 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ } // Save unit so we can do convertions between new/old units. g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(line_height_unit)); - + + // Enable and turn on only if selection includes an object with line height set. + InkToggleAction* lineHeightUnset = + INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextLineHeightUnsetAction")); + gtk_action_set_sensitive(GTK_ACTION(lineHeightUnset), query.line_height.set ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(lineHeightUnset), query.line_height.set ); + // Word spacing double wordSpacing; if (query.word_spacing.normal) wordSpacing = 0.0; @@ -1379,6 +1552,15 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ ege_select_one_action_update_sensitive( textOrientationAction ); + // Direction + int activeButton4 = 0; + if (query.direction.computed == SP_CSS_DIRECTION_LTR ) activeButton4 = 0; + if (query.direction.computed == SP_CSS_DIRECTION_RTL ) activeButton4 = 1; + + EgeSelectOneAction* textDirectionAction = + EGE_SELECT_ONE_ACTION( g_object_get_data( tbl, "TextDirectionAction" ) ); + ege_select_one_action_set_active( textDirectionAction, activeButton4 ); + } #ifdef DEBUG_TEXT @@ -1562,36 +1744,17 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje g_object_set_data( holder, "TextFontFamilyAction", act ); // Change style of drop-down from menu to list -#if GTK_CHECK_VERSION(3,0,0) - GtkCssProvider *css_provider = gtk_css_provider_new(); + auto css_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(css_provider, "#TextFontFamilyAction_combobox {\n" " -GtkComboBox-appears-as-list: true;\n" - "}\n" - "combobox window.popup scrolledwindow treeview separator {\n" - " -GtkWidget-wide-separators: true;\n" - " -GtkWidget-separator-height: 6;\n" "}\n", -1, NULL); - GdkScreen *screen = gdk_screen_get_default(); + auto screen = gdk_screen_get_default(); gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER); -#else - gtk_rc_parse_string ( - "style \"dropdown-as-list-style\"\n" - "{\n" - " GtkComboBox::appears-as-list = 1\n" - "}\n" - "widget \"*.TextFontFamilyAction_combobox\" style \"dropdown-as-list-style\"" - "style \"fontfamily-separator-style\"\n" - "{\n" - " GtkWidget::wide-separators = 1\n" - " GtkWidget::separator-height = 6\n" - "}\n" - "widget \"*gtk-combobox-popup-window.GtkScrolledWindow.GtkTreeView\" style \"fontfamily-separator-style\""); -#endif } /* Font size */ @@ -1610,7 +1773,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje _(tooltip.c_str()), NULL, GTK_TREE_MODEL(model_size), - 4, // Width in characters + 8, // Width in characters 0, // Extra list width NULL, // Cell layout NULL, // Separator @@ -1632,7 +1795,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje _("Font style"), NULL, GTK_TREE_MODEL(model_style), - 12, // Width in characters + 12, // Width in characters 0, // Extra list width NULL, // Cell layout NULL, // Separator @@ -1662,7 +1825,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje _("Toggle Subscript"), // Label _("Toggle subscript"), // Tooltip "text_subscript", // Icon (inkId) - secondarySize ); // Icon size + 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) ); @@ -1756,8 +1919,8 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje -1 ); EgeSelectOneAction* act = ege_select_one_action_new( "TextWritingModeAction", // Name - _("Writing mode"), // Label - _("Block progression"), // Tooltip + _("Writing mode"), // Label + _("Block progression"), // Tooltip NULL, // Icon name GTK_TREE_MODEL(model) ); // Model @@ -1830,6 +1993,52 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_text_orientation_changed), holder ); } + + // Text direction (predominant direction of horizontal text). + { + GtkListStore* model = gtk_list_store_new( 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN ); + + GtkTreeIter iter; + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, + 0, _("LTR"), + 1, _("Left to right text"), + 2, INKSCAPE_ICON("format-text-direction-horizontal"), + 3, true, + -1 ); + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, + 0, _("RTL"), + 1, _("Right to left text"), + 2, INKSCAPE_ICON("format-text-direction-r2l"), + 3, true, + -1 ); + + EgeSelectOneAction* act = ege_select_one_action_new( "TextDirectionAction", // Name + _("Text direction"), // Label + _("Text direction for normally horizontal text."), // Tooltip + NULL, // Icon name + GTK_TREE_MODEL(model) ); // Model + + g_object_set( act, "short_label", "NotUsed", NULL ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + g_object_set_data( holder, "TextDirectionAction", act ); + + ege_select_one_action_set_appearance( act, "full" ); + ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); + g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); + 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/text_direction", 0); + ege_select_one_action_set_active( act, mode ); + g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_text_direction_changed), holder ); + } + /* Line height unit tracker */ UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); tracker->prependUnit(unit_table.getUnit("")); // No unit @@ -1849,7 +2058,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje "TextLineHeightAction", /* name */ _("Line Height"), /* label */ _("Line:"), /* short label */ - _("Spacing between baselines (times font size)"), /* tooltip */ + _("Spacing between baselines"), /* tooltip */ "/tools/text/lineheight", /* preferences path */ 0.0, /* default */ GTK_WIDGET(desktop->canvas), /* focusTarget */ @@ -1888,7 +2097,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje "TextWordSpacingAction", /* name */ _("Word spacing"), /* label */ _("Word:"), /* short label */ - _("Spacing between words (px)"), /* tooltip */ + _("Spacing between words (px)"), /* tooltip */ "/tools/text/wordspacing", /* preferences path */ 0.0, /* default */ GTK_WIDGET(desktop->canvas), /* focusTarget */ @@ -1919,7 +2128,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje "TextLetterSpacingAction", /* name */ _("Letter spacing"), /* label */ _("Letter:"), /* short label */ - _("Spacing between letters (px)"), /* tooltip */ + _("Spacing between letters (px)"), /* tooltip */ "/tools/text/letterspacing", /* preferences path */ 0.0, /* default */ GTK_WIDGET(desktop->canvas), /* focusTarget */ @@ -1950,7 +2159,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje "TextDxAction", /* name */ _("Kerning"), /* label */ _("Kern:"), /* short label */ - _("Horizontal kerning (px)"), /* tooltip */ + _("Horizontal kerning (px)"), /* tooltip */ "/tools/text/dx", /* preferences path */ 0.0, /* default */ GTK_WIDGET(desktop->canvas), /* focusTarget */ @@ -1981,7 +2190,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje "TextDyAction", /* name */ _("Vertical Shift"), /* label */ _("Vert:"), /* short label */ - _("Vertical shift (px)"), /* tooltip */ + _("Vertical shift (px)"), /* tooltip */ "/tools/text/dy", /* preferences path */ 0.0, /* default */ GTK_WIDGET(desktop->canvas), /* focusTarget */ @@ -2012,7 +2221,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje "TextRotationAction", /* name */ _("Letter rotation"), /* label */ _("Rot:"), /* short label */ - _("Character rotation (degrees)"),/* tooltip */ + _("Character rotation (degrees)"), /* tooltip */ "/tools/text/rotation", /* preferences path */ 0.0, /* default */ GTK_WIDGET(desktop->canvas), /* focusTarget */ @@ -2033,6 +2242,32 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje g_object_set( G_OBJECT(eact), "iconId", "text_rotation", NULL ); } + /* Text line height unset */ + { + InkToggleAction* act = ink_toggle_action_new( "TextLineHeightUnsetAction", // Name + _("Unset line height"), // Label + _("If enabled, line height is set on part of selection. Click to unset."), + INKSCAPE_ICON("paint-unknown"), + secondarySize ); // Icon size + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_lineheight_unset_changed), holder ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/line_height_unset", false) ); + g_object_set_data( holder, "TextLineHeightUnsetAction", act ); + } + + /* Text outer style */ + { + InkToggleAction* act = ink_toggle_action_new( "TextOuterStyleAction", // Name + _("Show outer style"), // Label + _("Show style of outermost text element. The 'font-size' and 'line-height' values of the outermost text element determine the minimum line spacing in the block."), + INKSCAPE_ICON("text_outer_style"), + secondarySize ); // Icon size + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_outer_style_changed), holder ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/outer_style", false) ); + g_object_set_data( holder, "TextOuterStyleAction", act ); + } + // Is this necessary to call? Shouldn't hurt. sp_text_toolbox_selection_changed(desktop->getSelection(), holder); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 8113c9619..016eafdaa 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -27,7 +27,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #include <gtkmm/box.h> @@ -40,14 +40,10 @@ #include "../desktop-style.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" -#include "widgets/ege-output-action.h" -#include "widgets/ege-select-one-action.h" -#include "../graphlayout.h" #include "../helper/action.h" -#include "../helper/action-context.h" #include "icon.h" #include "ink-action.h" -#include "ink-comboboxentry-action.h" +#include "ink-toggle-action.h" #include "../inkscape.h" #include "ui/interface.h" #include "../shortcuts.h" @@ -64,7 +60,6 @@ #include "../widgets/widget-sizes.h" #include "../xml/attribute-record.h" #include "../xml/node-event-vector.h" -#include "../xml/repr.h" #include "ui/uxmanager.h" @@ -95,7 +90,6 @@ #include "zoom-toolbar.h" #include "toolbox.h" -#include <gtk/gtk.h> #include "ui/tools/tool-base.h" @@ -210,6 +204,7 @@ static struct { SP_VERB_CONTEXT_ERASER_PREFS, "/tools/eraser", _("TBD")}, { "/tools/lpetool", "lpetool_toolbox", 0, sp_lpetool_toolbox_prep, "LPEToolToolbar", SP_VERB_CONTEXT_LPETOOL_PREFS, "/tools/lpetool", _("TBD")}, + // If you change TextToolbar here, change it also in desktop-widget.cpp { "/tools/text", "text_toolbox", 0, sp_text_toolbox_prep, "TextToolbar", SP_VERB_INVALID, 0, 0}, { "/tools/dropper", "dropper_toolbox", 0, sp_dropper_toolbox_prep, "DropperToolbar", @@ -368,8 +363,6 @@ static gchar const * ui_descr = " <separator />" " <toolitem action='MeasureScaleAction' />" " <separator />" - " <toolitem action='MeasureOffsetAction' />" - " <separator />" " <toolitem action='measure_units_label' />" " <toolitem action='MeasureUnitsAction' />" " <toolitem action='MeasureIgnore1stAndLast' />" @@ -379,8 +372,9 @@ static gchar const * ui_descr = " <toolitem action='MeasureReverse' />" " <toolitem action='MeasureToPhantom' />" " <toolitem action='MeasureToGuides' />" - " <toolitem action='MeasureMarkDimension' />" " <toolitem action='MeasureToItem' />" + " <toolitem action='MeasureMarkDimension' />" + " <toolitem action='MeasureOffsetAction' />" " </toolbar>" " <toolbar name='StarToolbar'>" @@ -499,6 +493,13 @@ static gchar const * ui_descr = " <toolitem action='EraserModeAction' />" " <separator />" " <toolitem action='EraserWidthAction' />" + " <toolitem action='EraserPressureAction' />" + " <separator />" + " <toolitem action='EraserThinningAction' />" + " <separator />" + " <toolitem action='EraserCapRoundingAction' />" + " <separator />" + " <toolitem action='EraserTremorAction' />" " <separator />" " <toolitem action='EraserMassAction' />" " <separator />" @@ -507,18 +508,19 @@ static gchar const * ui_descr = " <toolbar name='TextToolbar'>" " <toolitem action='TextFontFamilyAction' />" - " <toolitem action='TextFontSizeAction' />" " <toolitem action='TextFontStyleAction' />" -// " <toolitem action='TextBoldAction' />" -// " <toolitem action='TextItalicAction' />" + " <separator />" + " <toolitem action='TextOuterStyleAction' />" + " <toolitem action='TextFontSizeAction' />" + " <toolitem action='TextLineHeightAction' />" + " <toolitem action='TextLineHeightUnitsAction' />" + " <toolitem action='TextLineHeightUnsetAction' />" " <separator />" " <toolitem action='TextAlignAction' />" " <separator />" " <toolitem action='TextSuperscriptAction' />" " <toolitem action='TextSubscriptAction' />" " <separator />" - " <toolitem action='TextLineHeightAction' />" - " <toolitem action='TextLineHeightUnitsAction' />" " <toolitem action='TextLetterSpacingAction' />" " <toolitem action='TextWordSpacingAction' />" " <toolitem action='TextDxAction' />" @@ -528,6 +530,8 @@ static gchar const * ui_descr = " <toolitem action='TextWritingModeAction' />" " <separator />" " <toolitem action='TextOrientationAction' />" + " <separator />" + " <toolitem action='TextDirectionAction' />" " </toolbar>" " <toolbar name='LPEToolToolbar'>" @@ -571,8 +575,14 @@ static gchar const * ui_descr = " <toolitem action='MeshToggleSidesAction' />" " <toolitem action='MeshMakeEllipticalAction' />" " <toolitem action='MeshPickColorsAction' />" + " <toolitem action='MeshFitInBoundingBoxAction' />" + " <separator />" + " <toolitem action='MeshShowHandlesAction' />" + " <toolitem action='MeshEditFillAction' />" + " <toolitem action='MeshEditStrokeAction' />" " <separator />" " <toolitem action='MeshWarningAction' />" + " <separator />" " <toolitem action='MeshSmoothAction' />" " </toolbar>" @@ -653,7 +663,7 @@ Glib::RefPtr<VerbAction> VerbAction::create(Inkscape::Verb* verb, Inkscape::Verb } VerbAction::VerbAction(Inkscape::Verb* verb, Inkscape::Verb* verb2, Inkscape::UI::View::View *view) : - Gtk::Action(Glib::ustring(verb->get_id()), Gtk::StockID(verb->get_image()), Glib::ustring(g_dpgettext2(NULL, "ContextVerb", verb->get_name())), Glib::ustring(_(verb->get_tip()))), + Gtk::Action(Glib::ustring(verb->get_id()), verb->get_image(), Glib::ustring(g_dpgettext2(NULL, "ContextVerb", verb->get_name())), Glib::ustring(_(verb->get_tip()))), verb(verb), verb2(verb2), view(view), @@ -668,7 +678,7 @@ VerbAction::~VerbAction() Gtk::Widget* VerbAction::create_menu_item_vfunc() { // First call in to get the icon rendered if present in SVG - Gtk::Widget *widget = sp_icon_get_icon( property_stock_id().get_value().get_string(), Inkscape::ICON_SIZE_MENU ); + Gtk::Widget *widget = sp_icon_get_icon( get_icon_name(), Inkscape::ICON_SIZE_MENU ); delete widget; widget = 0; @@ -1016,26 +1026,18 @@ static GtkWidget* toolboxNewCommon( GtkWidget* tb, BarId id, GtkPositionType /*h GtkWidget *ToolboxFactory::createToolToolbox() { -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *tb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + auto tb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_widget_set_name(tb, "ToolToolbox"); gtk_box_set_homogeneous(GTK_BOX(tb), FALSE); -#else - GtkWidget *tb = gtk_vbox_new(FALSE, 0); -#endif return toolboxNewCommon( tb, BAR_TOOL, GTK_POS_TOP ); } GtkWidget *ToolboxFactory::createAuxToolbox() { -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *tb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + auto tb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_widget_set_name(tb, "AuxToolbox"); gtk_box_set_homogeneous(GTK_BOX(tb), FALSE); -#else - GtkWidget *tb = gtk_vbox_new(FALSE, 0); -#endif return toolboxNewCommon( tb, BAR_AUX, GTK_POS_LEFT ); } @@ -1046,38 +1048,26 @@ GtkWidget *ToolboxFactory::createAuxToolbox() GtkWidget *ToolboxFactory::createCommandsToolbox() { -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *tb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + auto tb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_widget_set_name(tb, "CommandsToolbox"); gtk_box_set_homogeneous(GTK_BOX(tb), FALSE); -#else - GtkWidget *tb = gtk_vbox_new(FALSE, 0); -#endif return toolboxNewCommon( tb, BAR_COMMANDS, GTK_POS_LEFT ); } GtkWidget *ToolboxFactory::createSnapToolbox() { -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *tb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + auto tb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_widget_set_name(tb, "SnapToolbox"); gtk_box_set_homogeneous(GTK_BOX(tb), FALSE); -#else - GtkWidget *tb = gtk_vbox_new(FALSE, 0); -#endif return toolboxNewCommon( tb, BAR_SNAP, GTK_POS_LEFT ); } static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRate, guint digits, Inkscape::UI::Widget::UnitTracker *unit_tracker) { -#if WITH_GTKMM_3_0 - Glib::RefPtr<Gtk::Adjustment> adj = Glib::wrap(adjustment, true); - Inkscape::UI::Widget::SpinButton *inkSpinner = new Inkscape::UI::Widget::SpinButton(adj, climbRate, digits); -#else - Inkscape::UI::Widget::SpinButton *inkSpinner = new Inkscape::UI::Widget::SpinButton(*Glib::wrap(adjustment, true), climbRate, digits); -#endif + auto adj = Glib::wrap(adjustment, true); + auto inkSpinner = new Inkscape::UI::Widget::SpinButton(adj, climbRate, digits); inkSpinner->addUnitTracker(unit_tracker); inkSpinner = Gtk::manage( inkSpinner ); GtkWidget *widget = GTK_WIDGET( inkSpinner->gobj() ); @@ -1439,17 +1429,10 @@ void setup_aux_toolbox(GtkWidget *toolbox, SPDesktop *desktop) if ( aux_toolboxes[i].prep_func ) { // converted to GtkActions and UIManager - GtkWidget* kludge = dataHolders[aux_toolboxes[i].type_name]; - -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget* holder = gtk_grid_new(); - gtk_widget_set_name( holder, "ToolbarHolder" ); + auto kludge = dataHolders[aux_toolboxes[i].type_name]; + auto holder = gtk_grid_new(); + gtk_widget_set_name( holder, aux_toolboxes[i].ui_name ); gtk_grid_attach( GTK_GRID(holder), kludge, 2, 0, 1, 1); -#else - GtkWidget* holder = gtk_table_new( 1, 3, FALSE ); - gtk_table_attach( GTK_TABLE(holder), kludge, 2, 3, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0 ); -#endif - gchar* tmp = g_strdup_printf( "/ui/%s", aux_toolboxes[i].ui_name ); GtkWidget* toolBar = gtk_ui_manager_get_widget( mgr, tmp ); g_free( tmp ); @@ -1461,30 +1444,20 @@ void setup_aux_toolbox(GtkWidget *toolbox, SPDesktop *desktop) Inkscape::IconSize toolboxSize = ToolboxFactory::prefToSize("/toolbox/small"); gtk_toolbar_set_icon_size( GTK_TOOLBAR(toolBar), static_cast<GtkIconSize>(toolboxSize) ); - -#if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_hexpand(toolBar, TRUE); gtk_grid_attach( GTK_GRID(holder), toolBar, 0, 0, 1, 1); -#else - gtk_table_attach( GTK_TABLE(holder), toolBar, 0, 1, 0, 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0 ); -#endif if ( aux_toolboxes[i].swatch_verb_id != SP_VERB_INVALID ) { Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch( NULL, _(aux_toolboxes[i].swatch_tip) ); swatch->setDesktop( desktop ); swatch->setClickVerb( aux_toolboxes[i].swatch_verb_id ); swatch->setWatchedTool( aux_toolboxes[i].swatch_tool, true ); - GtkWidget *swatch_ = GTK_WIDGET( swatch->gobj() ); - -#if GTK_CHECK_VERSION(3,0,0) + auto swatch_ = GTK_WIDGET( swatch->gobj() ); gtk_widget_set_margin_left(swatch_, AUX_BETWEEN_BUTTON_GROUPS); gtk_widget_set_margin_right(swatch_, AUX_BETWEEN_BUTTON_GROUPS); gtk_widget_set_margin_top(swatch_, AUX_SPACING); gtk_widget_set_margin_bottom(swatch_, AUX_SPACING); gtk_grid_attach( GTK_GRID(holder), swatch_, 1, 0, 1, 1); -#else - gtk_table_attach( GTK_TABLE(holder), swatch_, 1, 2, 0, 1, (GtkAttachOptions)(GTK_SHRINK | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), AUX_BETWEEN_BUTTON_GROUPS, AUX_SPACING ); -#endif } if(i==0){ gtk_widget_show_all( holder ); diff --git a/src/widgets/tweak-toolbar.cpp b/src/widgets/tweak-toolbar.cpp index a185ea956..a6b8ba436 100644 --- a/src/widgets/tweak-toolbar.cpp +++ b/src/widgets/tweak-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #include "ui/widget/spinbutton.h" @@ -36,8 +36,8 @@ #include "widgets/ege-adjustment-action.h" #include "widgets/ege-output-action.h" #include "widgets/ege-select-one-action.h" -#include "widgets/ink-action.h" -#include "preferences.h" +#include "ink-radio-action.h" +#include "ink-toggle-action.h" #include "toolbox.h" #include "ui/icon-names.h" #include "ui/tools/tweak-tool.h" diff --git a/src/widgets/widget-sizes.h b/src/widgets/widget-sizes.h index 87c7ca2e0..186cf4730 100644 --- a/src/widgets/widget-sizes.h +++ b/src/widgets/widget-sizes.h @@ -28,6 +28,7 @@ #define STATUS_BAR_FONT_SIZE 10000 #define STATUS_ZOOM_WIDTH 57 +#define STATUS_ROTATION_WIDTH 57 #define SELECTED_STYLE_SB_WIDTH 48 #define SELECTED_STYLE_WIDTH 190 diff --git a/src/widgets/zoom-toolbar.cpp b/src/widgets/zoom-toolbar.cpp index 79feef86d..a961c0061 100644 --- a/src/widgets/zoom-toolbar.cpp +++ b/src/widgets/zoom-toolbar.cpp @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #include "zoom-toolbar.h" |
