diff options
| author | Markus Engel <markus.engel@tum.de> | 2013-03-29 23:52:42 +0000 |
|---|---|---|
| committer | Markus Engel <markus.engel@tum.de> | 2013-03-29 23:52:42 +0000 |
| commit | a168040d5a452544328a1e6ad35aaac351f94d44 (patch) | |
| tree | fae1ba829f543a473da281bd5fa6e4deabbf6912 /src/widgets | |
| parent | Removed function pointers from SPObject and subclasses. (diff) | |
| parent | Dutch translation update (diff) | |
| download | inkscape-a168040d5a452544328a1e6ad35aaac351f94d44.tar.gz inkscape-a168040d5a452544328a1e6ad35aaac351f94d44.zip | |
merged from trunk
(bzr r11608.1.56)
Diffstat (limited to 'src/widgets')
90 files changed, 3734 insertions, 2984 deletions
diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index 38180bd69..19410ee1d 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -36,7 +36,6 @@ set(widgets_SRC select-toolbar.cpp shrink-wrap-button.cpp sp-attribute-widget.cpp - sp-color-gtkselector.cpp sp-color-icc-selector.cpp sp-color-notebook.cpp sp-color-scales.cpp @@ -94,7 +93,6 @@ set(widgets_SRC select-toolbar.h shrink-wrap-button.h sp-attribute-widget.h - sp-color-gtkselector.h sp-color-icc-selector.h sp-color-notebook.h sp-color-scales.h diff --git a/src/widgets/Makefile_insert b/src/widgets/Makefile_insert index 7d6b413bd..46f0bd645 100644 --- a/src/widgets/Makefile_insert +++ b/src/widgets/Makefile_insert @@ -66,8 +66,6 @@ ink_common_sources += \ widgets/spiral-toolbar.h \ widgets/sp-attribute-widget.cpp \ widgets/sp-attribute-widget.h \ - widgets/sp-color-gtkselector.cpp \ - widgets/sp-color-gtkselector.h \ widgets/sp-color-icc-selector.cpp \ widgets/sp-color-icc-selector.h \ widgets/sp-color-notebook.cpp \ diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index 84434c88b..809050ad9 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -28,9 +28,9 @@ # include "config.h" #endif +#include "ui/widget/spinbutton.h" #include <glibmm/i18n.h> -#include "ui/widget/spinbutton.h" #include "toolbox.h" #include "arc-toolbar.h" @@ -92,7 +92,7 @@ static void sp_arctb_sensitivize( GObject *tbl, double v1, double v2 ) static void sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name, gchar const *other_name) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -128,8 +128,8 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v } sp_genericellipse_normalize(ge); - ((SPObject *)arc)->updateRepr(); - ((SPObject *)arc)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + (SP_OBJECT(arc))->updateRepr(); + (SP_OBJECT(arc))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); modmade = true; } @@ -163,7 +163,7 @@ static void sp_arctb_end_value_changed(GtkAdjustment *adj, GObject *tbl) static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setBool("/tools/shapes/arc/open", ege_select_one_action_get_active(act) != 0); @@ -419,7 +419,7 @@ void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObjec sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), (GObject *)holder)) + sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), G_OBJECT(holder))) ); g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); diff --git a/src/widgets/arc-toolbar.h b/src/widgets/arc-toolbar.h index 69d7b8a17..dba2fcd5a 100644 --- a/src/widgets/arc-toolbar.h +++ b/src/widgets/arc-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/box3d-toolbar.cpp b/src/widgets/box3d-toolbar.cpp index 2192ebfdc..e8b330375 100644 --- a/src/widgets/box3d-toolbar.cpp +++ b/src/widgets/box3d-toolbar.cpp @@ -28,9 +28,9 @@ # include "config.h" #endif +#include "ui/widget/spinbutton.h" #include <glibmm/i18n.h> -#include "ui/widget/spinbutton.h" #include "toolbox.h" #include "box3d-toolbar.h" @@ -227,7 +227,7 @@ static void box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObj static void box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis axis) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); SPDocument *document = sp_desktop_document(desktop); // quit if run by the attr_changed or selection changed listener @@ -431,7 +431,7 @@ void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject } sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), (GObject *)holder)) + sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), G_OBJECT(holder))) ); g_signal_connect(holder, "destroy", G_CALLBACK(delete_connection), connection); g_signal_connect(holder, "destroy", G_CALLBACK(purge_repr_listener), holder); diff --git a/src/widgets/box3d-toolbar.h b/src/widgets/box3d-toolbar.h index 50535b8de..d80934b01 100644 --- a/src/widgets/box3d-toolbar.h +++ b/src/widgets/box3d-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/button.cpp b/src/widgets/button.cpp index 45356601b..467f0d70e 100644 --- a/src/widgets/button.cpp +++ b/src/widgets/button.cpp @@ -25,8 +25,6 @@ #include "button.h" -static void sp_button_class_init (SPButtonClass *klass); -static void sp_button_init (SPButton *button); static void sp_button_dispose(GObject *object); #if GTK_CHECK_VERSION(3,0,0) @@ -50,37 +48,14 @@ static void sp_button_set_doubleclick_action (SPButton *button, SPAction *action static void sp_button_action_set_active (SPButton *button, bool active); static void sp_button_set_composed_tooltip (GtkWidget *widget, SPAction *action); -static GtkToggleButtonClass *parent_class; - -GType sp_button_get_type(void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPButtonClass), - 0, // base_init - 0, // base_finalize - (GClassInitFunc)sp_button_class_init, - 0, // class_finalize - 0, // class_data - sizeof(SPButton), - 0, // n_preallocs - (GInstanceInitFunc)sp_button_init, - 0 // value_table - }; - type = g_type_register_static(GTK_TYPE_TOGGLE_BUTTON, "SPButton", &info, static_cast<GTypeFlags>(0)); - } - return type; -} +G_DEFINE_TYPE(SPButton, sp_button, GTK_TYPE_TOGGLE_BUTTON); static void sp_button_class_init (SPButtonClass *klass) { - GObjectClass *object_class=(GObjectClass *)klass; - GtkWidgetClass *widget_class=(GtkWidgetClass *)klass; - GtkButtonClass *button_class=(GtkButtonClass *)klass; - - parent_class = (GtkToggleButtonClass *)g_type_class_peek_parent (klass); + GObjectClass *object_class=G_OBJECT_CLASS(klass); + GtkWidgetClass *widget_class=GTK_WIDGET_CLASS(klass); + GtkButtonClass *button_class=GTK_BUTTON_CLASS(klass); object_class->dispose = sp_button_dispose; #if GTK_CHECK_VERSION(3,0,0) @@ -120,10 +95,10 @@ static void sp_button_dispose(GObject *object) sp_button_set_doubleclick_action (button, NULL); } - button->c_set_active.~connection(); - button->c_set_sensitive.~connection(); + button->c_set_active.~connection(); + button->c_set_sensitive.~connection(); - ((GObjectClass *) (parent_class))->dispose(object); + (G_OBJECT_CLASS(sp_button_parent_class))->dispose(object); } @@ -185,7 +160,7 @@ sp_button_clicked (GtkButton *button) SPButton *sp_button=SP_BUTTON (button); if (sp_button->type == SP_BUTTON_TYPE_TOGGLE) { - ((GtkButtonClass *) (parent_class))->clicked (button); + (GTK_BUTTON_CLASS(sp_button_parent_class))->clicked (button); } } @@ -218,9 +193,7 @@ sp_button_perform_action (SPButton *button, gpointer /*data*/) GtkWidget * sp_button_new( Inkscape::IconSize size, SPButtonType type, SPAction *action, SPAction *doubleclick_action ) { - SPButton *button; - - button = (SPButton *)g_object_new (SP_TYPE_BUTTON, NULL); + SPButton *button = SP_BUTTON(g_object_new(SP_TYPE_BUTTON, NULL)); button->type = type; button->lsize = CLAMP( size, Inkscape::ICON_SIZE_MENU, Inkscape::ICON_SIZE_DECORATION ); @@ -232,7 +205,7 @@ sp_button_new( Inkscape::IconSize size, SPButtonType type, SPAction *action, SPA // The Inkscape style is no-relief buttons gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); - return (GtkWidget *) button; + return GTK_WIDGET(button); } void @@ -289,7 +262,7 @@ sp_button_set_action (SPButton *button, SPAction *action) } } - sp_button_set_composed_tooltip ((GtkWidget *) button, action); + sp_button_set_composed_tooltip(GTK_WIDGET(button), action); } static void @@ -342,3 +315,13 @@ sp_button_new_from_data( Inkscape::IconSize size, return button; } +/* + 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/calligraphy-toolbar.cpp b/src/widgets/calligraphy-toolbar.cpp index a0ae136e8..4cb4813b5 100644 --- a/src/widgets/calligraphy-toolbar.cpp +++ b/src/widgets/calligraphy-toolbar.cpp @@ -28,11 +28,9 @@ # include "config.h" #endif - +#include "ui/dialog/calligraphic-profile-rename.h" #include <glibmm/i18n.h> -#include "../ui/dialog/calligraphic-profile-rename.h" - #include "toolbox.h" #include "calligraphy-toolbar.h" @@ -74,6 +72,16 @@ using Inkscape::UI::PrefPusher; //######################## //## Calligraphy ## //######################## + +std::vector<Glib::ustring> get_presets_list() { + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + std::vector<Glib::ustring> presets = prefs->getAllDirs("/tools/calligraphic/preset"); + + return presets; +} + void update_presets_list(GObject *tbl) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -88,7 +96,7 @@ void update_presets_list(GObject *tbl) return; } - std::vector<Glib::ustring> presets = prefs->getAllDirs("/tools/calligraphic/preset"); + std::vector<Glib::ustring> presets = get_presets_list(); int ege_index = 1; for (std::vector<Glib::ustring>::iterator i = presets.begin(); i != presets.end(); ++i, ++ege_index) { @@ -233,22 +241,24 @@ static void sp_dcc_build_presets_list(GObject *tbl) // iterate over all presets to populate the list Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - std::vector<Glib::ustring> presets = prefs->getAllDirs("/tools/calligraphic/preset"); + std::vector<Glib::ustring> presets = get_presets_list(); int ii=1; for (std::vector<Glib::ustring>::iterator i = presets.begin(); i != presets.end(); ++i) { GtkTreeIter iter; Glib::ustring preset_name = prefs->getString(*i + "/name"); - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, _(preset_name.data()), 1, ii++, -1 ); + if (!preset_name.empty()) { + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, 0, _(preset_name.data()), 1, ii++, -1 ); + } } - { +/* { GtkTreeIter iter; gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, 0, _("Save..."), 1, ii, -1 ); g_object_set_data(tbl, "save_presets_index", GINT_TO_POINTER(ii)); - } + }*/ g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); @@ -259,7 +269,7 @@ static void sp_dcc_save_profile(GtkWidget * /*widget*/, GObject *tbl) { using Inkscape::UI::Dialog::CalligraphicProfileRename; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - SPDesktop *desktop = (SPDesktop *) g_object_get_data(tbl, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(tbl, "desktop" )); if (! desktop) { return; } @@ -268,15 +278,25 @@ static void sp_dcc_save_profile(GtkWidget * /*widget*/, GObject *tbl) return; } - CalligraphicProfileRename::show(desktop); + EgeSelectOneAction *sel = static_cast<EgeSelectOneAction *>(g_object_get_data(tbl, "profile_selector")); + //gint preset_index = ege_select_one_action_get_active( sel ); + Glib::ustring current_profile_name = _("No preset"); + if (ege_select_one_action_get_active_text( sel )) { + current_profile_name = ege_select_one_action_get_active_text( sel ); + } + + if (current_profile_name == _("No preset")) { + current_profile_name = ""; + } + CalligraphicProfileRename::show(desktop, current_profile_name); if ( !CalligraphicProfileRename::applied()) { // dialog cancelled update_presets_list (tbl); return; } - Glib::ustring profile_name = CalligraphicProfileRename::getProfileName(); + Glib::ustring new_profile_name = CalligraphicProfileRename::getProfileName(); - if (profile_name.empty()) { + if (new_profile_name.empty()) { // empty name entered update_presets_list (tbl); return; @@ -285,7 +305,7 @@ static void sp_dcc_save_profile(GtkWidget * /*widget*/, GObject *tbl) g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE)); // If there's a preset with the given name, find it and set save_path appropriately - std::vector<Glib::ustring> presets = prefs->getAllDirs("/tools/calligraphic/preset"); + std::vector<Glib::ustring> presets = get_presets_list(); int total_presets = presets.size(); int new_index = -1; Glib::ustring save_path; // profile pref path without a trailing slash @@ -293,13 +313,21 @@ static void sp_dcc_save_profile(GtkWidget * /*widget*/, GObject *tbl) int temp_index = 0; for (std::vector<Glib::ustring>::iterator i = presets.begin(); i != presets.end(); ++i, ++temp_index) { Glib::ustring name = prefs->getString(*i + "/name"); - if (!name.empty() && profile_name == name) { + if (!name.empty() && (new_profile_name == name || current_profile_name == name)) { new_index = temp_index; save_path = *i; break; } } + + if ( CalligraphicProfileRename::deleted() && new_index != -1) { + prefs->remove(save_path); + g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); + sp_dcc_build_presets_list (tbl); + return; + } + if (new_index == -1) { // no preset with this name, create new_index = total_presets + 1; @@ -327,7 +355,7 @@ static void sp_dcc_save_profile(GtkWidget * /*widget*/, GObject *tbl) g_warning("Bad key when writing preset: %s\n", widget_name); } } - prefs->setString(save_path + "/name", profile_name); + prefs->setString(save_path + "/name", new_profile_name); g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); sp_dcc_build_presets_list (tbl); @@ -338,7 +366,7 @@ static void sp_ddc_change_profile(EgeSelectOneAction* act, GObject* tbl) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint preset_index = ege_select_one_action_get_active( act ); + guint preset_index = ege_select_one_action_get_active( act ); // This is necessary because EgeSelectOneAction spams us with GObject "changed" signal calls // even when the preset is not changed. It would be good to replace it with something more // modern. Index 0 means "No preset", so we don't do anything. @@ -346,6 +374,7 @@ static void sp_ddc_change_profile(EgeSelectOneAction* act, GObject* tbl) return; } +/* gint save_presets_index = GPOINTER_TO_INT(g_object_get_data(tbl, "save_presets_index")); if (preset_index == save_presets_index) { @@ -353,14 +382,19 @@ static void sp_ddc_change_profile(EgeSelectOneAction* act, GObject* tbl) sp_dcc_save_profile(NULL, tbl); return; } +*/ if (g_object_get_data(tbl, "presets_blocked")) { return; } // preset_index is one-based so we subtract 1 - std::vector<Glib::ustring> presets = prefs->getAllDirs("/tools/calligraphic/preset"); - Glib::ustring preset_path = presets.at(preset_index - 1); + std::vector<Glib::ustring> presets = get_presets_list(); + + Glib::ustring preset_path = ""; + if (preset_index - 1 < presets.size()) { + preset_path = presets.at(preset_index - 1); + } if (!preset_path.empty()) { g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE)); //temporarily block the selector so no one will updadte it while we're reading it @@ -391,9 +425,16 @@ static void sp_ddc_change_profile(EgeSelectOneAction* act, GObject* tbl) } } g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); + } else { + ege_select_one_action_set_active(act, 0); } } +static void sp_ddc_edit_profile(GtkAction * /*act*/, GObject* tbl) +{ + sp_dcc_save_profile(NULL, tbl); +} + void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -595,6 +636,18 @@ void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions g_signal_connect(G_OBJECT(act1), "changed", G_CALLBACK(sp_ddc_change_profile), holder); gtk_action_group_add_action(mainActions, GTK_ACTION(act1)); } + + /*calligraphic profile editor */ + { + InkAction* inky = ink_action_new( "ProfileEditAction", + _("Add/Edit Profile"), + _("Add or edit calligraphic profile"), + GTK_STOCK_PROPERTIES, + Inkscape::ICON_SIZE_DECORATION ); + g_object_set( inky, "short_label", _("Edit"), NULL ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_ddc_edit_profile), (GObject*)holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } } } diff --git a/src/widgets/calligraphy-toolbar.h b/src/widgets/calligraphy-toolbar.h index 5b2e3c5d4..9650e03b1 100644 --- a/src/widgets/calligraphy-toolbar.h +++ b/src/widgets/calligraphy-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); void update_presets_list(GObject *tbl); diff --git a/src/widgets/connector-toolbar.cpp b/src/widgets/connector-toolbar.cpp index 2b00856ec..7c72f8e0c 100644 --- a/src/widgets/connector-toolbar.cpp +++ b/src/widgets/connector-toolbar.cpp @@ -78,13 +78,6 @@ using Inkscape::UI::PrefPusher; //## Connector ## //######################### -static void sp_connector_mode_toggled( GtkToggleAction* act, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/connector/mode", - gtk_toggle_action_get_active( act )); -} - static void sp_connector_path_set_avoid(void) { cc_selection_set_avoid(true); @@ -98,7 +91,7 @@ static void sp_connector_path_set_ignore(void) static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl ) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); Inkscape::Selection * selection = sp_desktop_selection(desktop); SPDocument *doc = sp_desktop_document(desktop); @@ -123,7 +116,7 @@ static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl bool modmade = false; GSList *l = (GSList *) selection->itemList(); while (l) { - SPItem *item = (SPItem *) l->data; + SPItem *item = SP_ITEM(l->data); if (cc_item_is_connector(item)) { item->setAttribute( "inkscape:connector-type", @@ -148,7 +141,7 @@ static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); Inkscape::Selection * selection = sp_desktop_selection(desktop); SPDocument *doc = sp_desktop_document(desktop); @@ -172,7 +165,7 @@ static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) bool modmade = false; GSList *l = (GSList *) selection->itemList(); while (l) { - SPItem *item = (SPItem *) l->data; + SPItem *item = SP_ITEM(l->data); if (cc_item_is_connector(item)) { item->setAttribute( "inkscape:connector-curvature", @@ -198,7 +191,7 @@ static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) static void connector_spacing_changed(GtkAdjustment *adj, GObject* tbl) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); SPDocument *doc = sp_desktop_document(desktop); if (!DocumentUndo::getUndoSensitive(doc)) { @@ -303,26 +296,6 @@ static void connector_tb_event_attr_changed(Inkscape::XML::Node *repr, } } -static void sp_connector_new_connection_point(GtkWidget *, GObject *tbl) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - SPConnectorContext* cc = SP_CONNECTOR_CONTEXT(desktop->event_context); - - if (cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE) { - cc_create_connection_point(cc); - } -} - -static void sp_connector_remove_connection_point(GtkWidget *, GObject *tbl) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - SPConnectorContext* cc = SP_CONNECTOR_CONTEXT(desktop->event_context); - - if (cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE) { - cc_remove_connection_point(cc); - } -} - static Inkscape::XML::NodeEventVector connector_tb_repr_events = { NULL, /* child_added */ NULL, /* child_removed */ @@ -351,22 +324,6 @@ void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions, Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - // Editing mode toggle button - { - InkToggleAction* act = ink_toggle_action_new( "ConnectorEditModeAction", - _("EditMode"), - _("Switch between connection point editing and connector drawing mode"), - INKSCAPE_ICON("connector-edit"), - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - - bool tbuttonstate = prefs->getBool("/tools/connector/mode"); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE )); - g_object_set_data( holder, "mode", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_connector_mode_toggled), holder ); - } - - { InkAction* inky = ink_action_new( "ConnectorAvoidAction", _("Avoid"), @@ -461,7 +418,7 @@ void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions, gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE )); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_directed_graph_layout_toggled), holder ); - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_connector_toolbox_selection_changed), (GObject *)holder)); + sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_connector_toolbox_selection_changed), holder)); } // Avoid overlaps toggle button @@ -480,30 +437,6 @@ void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions, } - // New connection point button - { - InkAction* inky = ink_action_new( "ConnectorNewConnPointAction", - _("New connection point"), - _("Add a new connection point to the currently selected item"), - INKSCAPE_ICON("connector-new-connpoint"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_new_connection_point), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - // Remove selected connection point button - - { - InkAction* inky = ink_action_new( "ConnectorRemoveConnPointAction", - _("Remove connection point"), - _("Remove the currently selected connection point"), - INKSCAPE_ICON("connector-remove-connpoint"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_remove_connection_point), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - // Code to watch for changes to the connector-spacing attribute in // the XML. Inkscape::XML::Node *repr = desktop->namedview->getRepr(); diff --git a/src/widgets/connector-toolbar.h b/src/widgets/connector-toolbar.h index 6e69cf047..2ab26e56c 100644 --- a/src/widgets/connector-toolbar.h +++ b/src/widgets/connector-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_connector_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 81361f0f9..4af7c0795 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -82,11 +82,6 @@ using Inkscape::UI::UXManager; using Inkscape::UI::ToolboxFactory; using ege::AppearTimeTracker; -#ifdef WITH_INKBOARD -#endif - - - enum { ACTIVATE, DEACTIVATE, @@ -301,10 +296,10 @@ GType SPDesktopWidget::getType(void) static void sp_desktop_widget_class_init (SPDesktopWidgetClass *klass) { - dtw_parent_class = (SPViewWidgetClass*)g_type_class_peek_parent (klass); + dtw_parent_class = SP_VIEW_WIDGET_CLASS(g_type_class_peek_parent(klass)); - GObjectClass *object_class = (GObjectClass *) klass; - GtkWidgetClass *widget_class = (GtkWidgetClass *) klass; + GObjectClass *object_class = G_OBJECT_CLASS(klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); object_class->dispose = sp_desktop_widget_dispose; @@ -313,22 +308,30 @@ sp_desktop_widget_class_init (SPDesktopWidgetClass *klass) } /** + * Callback for changes in size of the canvas table (i.e. the container for + * the canvas, the rulers etc). + * + * This adjusts the range of the rulers when the dock container is adjusted + * (fixes lp:950552) + */ +static void +canvas_tbl_size_allocate(GtkWidget *widget, + GdkRectangle *allocation, + gpointer data) +{ + SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(data); + sp_desktop_widget_update_rulers (dtw); +} + +/** * Callback for SPDesktopWidget object initialization. */ void SPDesktopWidget::init( SPDesktopWidget *dtw ) { - GtkWidget *widget; - GtkWidget *tbl; - GtkWidget *canvas_tbl; - - GtkWidget *eventbox; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); new (&dtw->modified_connection) sigc::connection(); - widget = GTK_WIDGET (dtw); - dtw->window = 0; dtw->desktop = NULL; dtw->_interaction_disabled_counter = 0; @@ -336,7 +339,6 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) /* Main table */ #if GTK_CHECK_VERSION(3,0,0) dtw->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - gtk_box_set_homogeneous(GTK_BOX(dtw->vbox), FALSE); #else dtw->vbox = gtk_vbox_new (FALSE, 0); #endif @@ -344,7 +346,6 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) #if GTK_CHECK_VERSION(3,0,0) dtw->statusbar = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_set_homogeneous(GTK_BOX(dtw->statusbar), FALSE); #else dtw->statusbar = gtk_hbox_new (FALSE, 0); #endif @@ -356,15 +357,20 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) dtw->panels = new SwatchesPanel("/embedded/swatches"); 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_box_set_homogeneous(GTK_BOX(dtw->hbox), FALSE); #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); @@ -382,53 +388,73 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) ToolboxFactory::setOrientation( dtw->tool_toolbox, GTK_ORIENTATION_VERTICAL ); gtk_box_pack_start( GTK_BOX(dtw->hbox), dtw->tool_toolbox, FALSE, TRUE, 0 ); - tbl = gtk_table_new (2, 3, FALSE); - gtk_box_pack_start( GTK_BOX(dtw->hbox), tbl, TRUE, TRUE, 1 ); - - canvas_tbl = gtk_table_new (3, 3, FALSE); - /* Horizontal ruler */ - eventbox = gtk_event_box_new (); + GtkWidget *eventbox = gtk_event_box_new (); dtw->hruler = sp_ruler_new(GTK_ORIENTATION_HORIZONTAL); dtw->hruler_box = eventbox; - sp_ruler_set_metric(SP_RULER(dtw->hruler), SP_PT); + sp_ruler_set_unit(SP_RULER(dtw->hruler), SP_PT); gtk_widget_set_tooltip_text (dtw->hruler_box, gettext(sp_unit_get_plural (&sp_unit_get_by_id(SP_UNIT_PT)))); gtk_container_add (GTK_CONTAINER (eventbox), dtw->hruler); - gtk_table_attach (GTK_TABLE (canvas_tbl), eventbox, 1, 2, 0, 1, (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(GTK_FILL), - gtk_widget_get_style(widget)->xthickness, 0); g_signal_connect (G_OBJECT (eventbox), "button_press_event", G_CALLBACK (sp_dt_hruler_event), 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 = gtk_grid_new(); + dtw->canvas_tbl = gtk_grid_new(); + + gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), eventbox, 1, 0, 1, 1); +#else + GtkWidget *tbl = gtk_table_new(2, 3, FALSE); + dtw->canvas_tbl = gtk_table_new(3, 3, FALSE); + + gtk_table_attach(GTK_TABLE(dtw->canvas_tbl), + eventbox, + 1, 2, 0, 1, + GTK_FILL, GTK_FILL, + 0, 0); +#endif + + gtk_box_pack_start( GTK_BOX(dtw->hbox), tbl, TRUE, TRUE, 1 ); + /* Vertical ruler */ eventbox = gtk_event_box_new (); dtw->vruler = sp_ruler_new(GTK_ORIENTATION_VERTICAL); dtw->vruler_box = eventbox; - sp_ruler_set_metric (SP_RULER (dtw->vruler), SP_PT); + sp_ruler_set_unit (SP_RULER (dtw->vruler), SP_PT); gtk_widget_set_tooltip_text (dtw->vruler_box, gettext(sp_unit_get_plural (&sp_unit_get_by_id(SP_UNIT_PT)))); gtk_container_add (GTK_CONTAINER (eventbox), GTK_WIDGET (dtw->vruler)); - gtk_table_attach (GTK_TABLE (canvas_tbl), eventbox, 0, 1, 1, 2, (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(GTK_FILL), 0, - gtk_widget_get_style(widget)->ythickness); - 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); - g_signal_connect (G_OBJECT (eventbox), "motion_notify_event", G_CALLBACK (sp_dt_vruler_event), dtw); - /* Horizontal scrollbar */ - dtw->hadj = (GtkAdjustment *) 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_grid_attach(GTK_GRID(dtw->canvas_tbl), eventbox, 0, 1, 1, 1); #else - dtw->hscrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (dtw->hadj)); + gtk_table_attach(GTK_TABLE (dtw->canvas_tbl), + eventbox, + 0, 1, 1, 2, + GTK_FILL, GTK_FILL, + 0, 0); #endif - gtk_table_attach (GTK_TABLE (canvas_tbl), dtw->hscrollbar, 1, 2, 2, 3, (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(GTK_SHRINK), 0, 0); - /* Vertical scrollbar and the sticky zoom button */ + 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); + g_signal_connect (G_OBJECT (eventbox), "motion_notify_event", G_CALLBACK (sp_dt_vruler_event), 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_grid_attach(GTK_GRID(dtw->canvas_tbl), dtw->hscrollbar, 1, 2, 1, 1); dtw->vscrollbar_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - gtk_box_set_homogeneous(GTK_BOX(dtw->vscrollbar_box), FALSE); #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, SP_BUTTON_TYPE_TOGGLE, NULL, @@ -437,15 +463,25 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dtw->sticky_zoom), prefs->getBool("/options/stickyzoom/value")); gtk_box_pack_start (GTK_BOX (dtw->vscrollbar_box), dtw->sticky_zoom, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (dtw->sticky_zoom), "toggled", G_CALLBACK (sp_dtw_sticky_zoom_toggled), dtw); - dtw->vadj = (GtkAdjustment *) gtk_adjustment_new (0.0, -4000.0, 4000.0, 10.0, 100.0, 4.0); + + // 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)); #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); - gtk_table_attach (GTK_TABLE (canvas_tbl), dtw->vscrollbar_box, 2, 3, 0, 2, (GtkAttachOptions)(GTK_SHRINK), (GtkAttachOptions)(GTK_FILL), 0, 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 ); @@ -476,7 +512,16 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) #else cms_adjust_set_sensitive(dtw, FALSE); #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - gtk_table_attach( GTK_TABLE(canvas_tbl), dtw->cms_adjust, 2, 3, 2, 3, (GtkAttachOptions)(GTK_SHRINK), (GtkAttachOptions)(GTK_SHRINK), 0, 0); + +#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(); @@ -491,6 +536,9 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) gtk_widget_set_can_focus (GTK_WIDGET (dtw->canvas), TRUE); + 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) GdkRGBA white = {1,1,1,1}; gtk_widget_override_background_color(GTK_WIDGET(dtw->canvas), @@ -500,17 +548,22 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) 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 - + // TODO: Extension event stuff has been removed from public API in GTK+ 3 // Need to check that this hasn't broken anything -#if !GTK_CHECK_VERSION(3,0,0) if ( prefs->getBool("/options/useextinput/value", true) ) gtk_widget_set_extension_events(GTK_WIDGET (dtw->canvas) , GDK_EXTENSION_EVENTS_ALL); //set extension events for tablets, unless disabled in preferences #endif g_signal_connect (G_OBJECT (dtw->canvas), "event", G_CALLBACK (sp_desktop_widget_event), dtw); - gtk_table_attach (GTK_TABLE (canvas_tbl), GTK_WIDGET(dtw->canvas), 1, 2, 1, 2, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), 0, 0); + +#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 = @@ -520,8 +573,13 @@ 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(); +#else Gtk::HPaned *paned = new Gtk::HPaned(); - paned->pack1(*Glib::wrap(canvas_tbl)); +#endif + + paned->pack1(*Glib::wrap(dtw->canvas_tbl)); paned->pack2(dtw->dock->getWidget(), Gtk::FILL); /* Prevent the paned from catching F6 and F8 by unsetting the default callbacks */ @@ -530,12 +588,24 @@ 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); + gtk_grid_attach(GTK_GRID(tbl), GTK_WIDGET (paned->gobj()), 1, 1, 1, 1); +#else gtk_table_attach (GTK_TABLE (tbl), GTK_WIDGET (paned->gobj()), 1, 2, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0); +#endif } else { - gtk_table_attach (GTK_TABLE (tbl), GTK_WIDGET (canvas_tbl), 1, 2, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), +#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), GTK_WIDGET (dtw->canvas_tbl), 1, 1, 1, 1); +#else + gtk_table_attach (GTK_TABLE (tbl), GTK_WIDGET (dtw->canvas_tbl), 1, 2, 1, 2, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0); +#endif } dtw->selected_style = new Inkscape::UI::Widget::SelectedStyle(true); @@ -573,35 +643,66 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) dtw->zoom_update = g_signal_connect (G_OBJECT (dtw->zoom_status), "populate_popup", G_CALLBACK (sp_dtw_zoom_populate_popup), dtw); // cursor coordinates - dtw->coord_status = gtk_table_new (5, 2, FALSE); +#if GTK_CHECK_VERSION(3,0,0) + dtw->coord_status = gtk_grid_new(); + 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); + 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), -#if GTK_CHECK_VERSION(3,0,0) - gtk_separator_new(GTK_ORIENTATION_VERTICAL), -#else gtk_vseparator_new(), + 0, 1, 0, 2, + GTK_FILL, GTK_FILL, 0, 0); #endif - 0,1, 0,2, GTK_FILL, GTK_FILL, 0, 0); + eventbox = gtk_event_box_new (); gtk_container_add (GTK_CONTAINER (eventbox), dtw->coord_status); gtk_widget_set_tooltip_text (eventbox, _("Cursor coordinates")); GtkWidget *label_x = gtk_label_new(_("X:")); gtk_misc_set_alignment (GTK_MISC(label_x), 0.0, 0.5); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(dtw->coord_status), + label_x, 1, 0, 1, 1); +#else gtk_table_attach(GTK_TABLE(dtw->coord_status), label_x, 1,2, 0,1, GTK_FILL, GTK_FILL, 0, 0); +#endif + GtkWidget *label_y = gtk_label_new(_("Y:")); gtk_misc_set_alignment (GTK_MISC(label_y), 0.0, 0.5); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(dtw->coord_status), label_y, 1, 1, 1, 1); +#else 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); gtk_label_set_markup( GTK_LABEL(dtw->coord_status_x), "<tt> 0.00 </tt>" ); gtk_misc_set_alignment (GTK_MISC(dtw->coord_status_x), 1.0, 0.5); dtw->coord_status_y = gtk_label_new(NULL); gtk_label_set_markup( GTK_LABEL(dtw->coord_status_y), "<tt> 0.00 </tt>" ); gtk_misc_set_alignment (GTK_MISC(dtw->coord_status_y), 1.0, 0.5); + GtkWidget* label_z = gtk_label_new(_("Z:")); + +#if GTK_CHECK_VERSION(3,0,0) + 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), dtw->zoom_status, 4, 0, 1, 2); +#else 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), gtk_label_new(_("Z:")), 3,4, 0,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 + sp_set_font_size_smaller (dtw->coord_status); gtk_box_pack_end (GTK_BOX (statusbar_tail), eventbox, FALSE, FALSE, 1); @@ -658,6 +759,13 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) } overallTimer = 0; } + + // Ensure that ruler ranges are updated correctly whenever the canvas table + // is resized + g_signal_connect (G_OBJECT (dtw->canvas_tbl), + "size-allocate", + G_CALLBACK (canvas_tbl_size_allocate), + dtw); } /** @@ -667,6 +775,10 @@ static void sp_desktop_widget_dispose(GObject *object) { SPDesktopWidget *dtw = SP_DESKTOP_WIDGET (object); + if (dtw == NULL) { + return; + } + UXManager::getInstance()->delTrack(dtw); if (dtw->desktop) { @@ -679,7 +791,10 @@ static void sp_desktop_widget_dispose(GObject *object) 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); 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); + + dtw->layer_selector->setDesktop(NULL); dtw->layer_selector->unreference(); inkscape_remove_desktop (dtw->desktop); // clears selection too dtw->modified_connection.disconnect(); @@ -705,18 +820,21 @@ static void sp_desktop_widget_dispose(GObject *object) void SPDesktopWidget::updateTitle(gchar const* uri) { - Gtk::Window *window = (Gtk::Window*)g_object_get_data(G_OBJECT(this), "window"); + Gtk::Window *window = static_cast<Gtk::Window*>(g_object_get_data(G_OBJECT(this), "window")); if (window) { gchar const *fname = uri; GString *name = g_string_new (""); - gchar const *grayscalename = "(grayscale) "; - gchar const *grayscalenamecomma = ", grayscale"; - gchar const *printcolorsname = "(print colors preview) "; - gchar const *printcolorsnamecomma = ", print colors preview"; - gchar const *colormodename = ""; - gchar const *colormodenamecomma = ""; + gchar const *grayscalename = N_("grayscale"); + gchar const *grayscalenamecomma = N_(", grayscale"); + gchar const *printcolorsname = N_("print colors preview"); + gchar const *printcolorsnamecomma = N_(", print colors preview"); + gchar const *outlinename = N_("outline"); + gchar const *nofiltersname = N_("no filters"); + gchar const *colormodename = NULL; + gchar const *colormodenamecomma = NULL; + gchar const *rendermodename = NULL; gchar const *modifiedname = ""; SPDocument *doc = this->desktop->doc(); if (doc->isModifiedSinceSave()) { @@ -730,22 +848,40 @@ SPDesktopWidget::updateTitle(gchar const* uri) colormodename = printcolorsname; colormodenamecomma = printcolorsnamecomma; } + if (this->desktop->getMode() == Inkscape::RENDERMODE_OUTLINE) { + rendermodename = outlinename; + } else if (this->desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) { + rendermodename = nofiltersname; + } + if (this->desktop->number > 1) { - if (this->desktop->getMode() == Inkscape::RENDERMODE_OUTLINE) { - g_string_printf (name, _("%s%s: %d (outline%s) - Inkscape"), modifiedname, fname, this->desktop->number, colormodenamecomma); - } else if (this->desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) { - g_string_printf (name, _("%s%s: %d (no filters%s) - Inkscape"), modifiedname, fname, this->desktop->number, colormodenamecomma); + if (rendermodename) { + if (colormodenamecomma) { + g_string_printf (name, _("%s%s: %d (%s%s) - Inkscape"), modifiedname, fname, this->desktop->number, _(rendermodename), _(colormodenamecomma)); + } else { + g_string_printf (name, _("%s%s: %d (%s) - Inkscape"), modifiedname, fname, this->desktop->number, _(rendermodename)); + } } else { - g_string_printf (name, _("%s%s: %d %s- Inkscape"), modifiedname, fname, this->desktop->number, colormodename); + if (colormodename) { + g_string_printf (name, _("%s%s: %d (%s) - Inkscape"), modifiedname, fname, this->desktop->number, _(colormodename)); + } else { + g_string_printf (name, _("%s%s: %d - Inkscape"), modifiedname, fname, this->desktop->number); + } } } else { - if (this->desktop->getMode() == Inkscape::RENDERMODE_OUTLINE) { - g_string_printf (name, _("%s%s (outline%s) - Inkscape"), modifiedname, fname, colormodenamecomma); - } else if (this->desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) { - g_string_printf (name, _("%s%s (no filters%s) - Inkscape"), modifiedname, fname, colormodenamecomma); + if (rendermodename) { + if (colormodenamecomma) { + g_string_printf (name, _("%s%s (%s%s) - Inkscape"), modifiedname, fname, _(rendermodename), _(colormodenamecomma)); + } else { + g_string_printf (name, _("%s%s (%s) - Inkscape"), modifiedname, fname, _(rendermodename)); + } } else { - g_string_printf (name, _("%s%s %s- Inkscape"), modifiedname, fname, colormodename); + if (colormodename) { + g_string_printf (name, _("%s%s (%s) - Inkscape"), modifiedname, fname, _(colormodename)); + } else { + g_string_printf (name, _("%s%s - Inkscape"), modifiedname, fname); + } } } window->set_title (name->str); @@ -866,12 +1002,13 @@ sp_desktop_widget_event (GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dt if (GTK_WIDGET_CLASS (dtw_parent_class)->event) { return (* GTK_WIDGET_CLASS (dtw_parent_class)->event) (widget, event); } else { - // The keypress events need to be passed to desktop handler explicitly, - // because otherwise the event contexts only receive keypresses when the mouse cursor - // is over the canvas. This redirection is only done for keypresses and only if there's no + // The key press/release events need to be passed to desktop handler explicitly, + // because otherwise the event contexts only receive key events when the mouse cursor + // is over the canvas. This redirection is only done for key events and only if there's no // current item on the canvas, because item events and all mouse events are caught // and passed on by the canvas acetate (I think). --bb - if (event->type == GDK_KEY_PRESS && !dtw->canvas->current_item) { + if ((event->type == GDK_KEY_PRESS || event->type == GDK_KEY_RELEASE) + && !dtw->canvas->current_item) { return sp_desktop_root_handler (NULL, event, dtw->desktop); } } @@ -994,7 +1131,7 @@ SPDesktopWidget::shutdown() switch (response) { case GTK_RESPONSE_YES: { - Gtk::Window *window = (Gtk::Window*)g_object_get_data(G_OBJECT(this), "window"); + Gtk::Window *window = static_cast<Gtk::Window*>(g_object_get_data(G_OBJECT(this), "window")); doc->doRef(); sp_namedview_document_from_window(desktop); @@ -1058,7 +1195,7 @@ SPDesktopWidget::shutdown() { doc->doRef(); - Gtk::Window *window = (Gtk::Window*)g_object_get_data(G_OBJECT(this), "window"); + Gtk::Window *window = static_cast<Gtk::Window*>(g_object_get_data(G_OBJECT(this), "window")); if (sp_file_save_dialog(*window, doc, Inkscape::Extension::FILE_SAVE_METHOD_INKSCAPE_SVG)) { doc->doUnref(); @@ -1170,7 +1307,7 @@ SPDesktopWidget::getWindowGeometry (gint &x, gint &y, gint &w, gint &h) gboolean vis = gtk_widget_get_visible (GTK_WIDGET(this)); (void)vis; // TODO figure out why it is here but not used. - Gtk::Window *window = (Gtk::Window*)g_object_get_data(G_OBJECT(this), "window"); + Gtk::Window *window = static_cast<Gtk::Window*>(g_object_get_data(G_OBJECT(this), "window")); if (window) { @@ -1182,7 +1319,7 @@ SPDesktopWidget::getWindowGeometry (gint &x, gint &y, gint &w, gint &h) void SPDesktopWidget::setWindowPosition (Geom::Point p) { - Gtk::Window *window = (Gtk::Window*)g_object_get_data(G_OBJECT(this), "window"); + Gtk::Window *window = static_cast<Gtk::Window*>(g_object_get_data(G_OBJECT(this), "window")); if (window) { @@ -1193,7 +1330,7 @@ SPDesktopWidget::setWindowPosition (Geom::Point p) void SPDesktopWidget::setWindowSize (gint w, gint h) { - Gtk::Window *window = (Gtk::Window*)g_object_get_data(G_OBJECT(this), "window"); + Gtk::Window *window = static_cast<Gtk::Window*>(g_object_get_data(G_OBJECT(this), "window")); if (window) { @@ -1211,10 +1348,10 @@ SPDesktopWidget::setWindowSize (gint w, gint h) void SPDesktopWidget::setWindowTransient (void *p, int transient_policy) { - Gtk::Window *window = (Gtk::Window*)g_object_get_data(G_OBJECT(this), "window"); + Gtk::Window *window = static_cast<Gtk::Window*>(g_object_get_data(G_OBJECT(this), "window")); if (window) { - GtkWindow *w = (GtkWindow *) window->gobj(); + GtkWindow *w = GTK_WINDOW(window->gobj()); gtk_window_set_transient_for (GTK_WINDOW(p), w); /* @@ -1459,7 +1596,7 @@ SPDesktopWidget::setToolboxSelectOneValue (gchar const *id, int value) { gpointer hb = sp_search_by_data_recursive(aux_toolbox, (gpointer) id); if (hb) { - ege_select_one_action_set_active((EgeSelectOneAction*) hb, value); + ege_select_one_action_set_active(EGE_SELECT_ONE_ACTION(hb), value); } } @@ -1581,59 +1718,25 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) return dtw; } -void -SPDesktopWidget::viewSetPosition (Geom::Point p) -{ - Geom::Point const origin = ( p - ruler_origin ); - gdouble hlower, hupper, hmax_range; - gdouble vlower, vupper, vmax_range; - sp_ruler_get_range(SP_RULER(hruler), &hlower, &hupper, NULL, &hmax_range); - sp_ruler_set_range(SP_RULER(hruler), hlower, hupper, origin[Geom::X], hmax_range); - sp_ruler_get_range(SP_RULER(vruler), &vlower, &vupper, NULL, &vmax_range); - sp_ruler_set_range(SP_RULER(vruler), vlower, vupper, origin[Geom::Y], vmax_range); -} void sp_desktop_widget_update_rulers (SPDesktopWidget *dtw) { - sp_desktop_widget_update_hruler(dtw); - sp_desktop_widget_update_vruler(dtw); -} - -void -sp_desktop_widget_update_hruler (SPDesktopWidget *dtw) -{ - /* The viewbox (in integers) must exactly match the size of SPCanvasbuf's pixel buffer. - * This is important because the former is being used for drawing the ruler, whereas - * the latter is used for drawing e.g. the grids and guides. Only when the viewbox - * coincides with the pixel buffer, everything will line up nicely. - */ - Geom::IntRect viewbox = dtw->canvas->getViewboxIntegers(); - gdouble position; - - double const scale = dtw->desktop->current_zoom(); - double s = viewbox.min()[Geom::X] / scale - dtw->ruler_origin[Geom::X]; - double e = viewbox.max()[Geom::X] / scale - dtw->ruler_origin[Geom::X]; - sp_ruler_get_range(SP_RULER(dtw->hruler), NULL, NULL, &position, NULL); - sp_ruler_set_range(SP_RULER(dtw->hruler), s, e, position, (e - s)); -} + Geom::Rect viewbox = dtw->desktop->get_display_area(); -void -sp_desktop_widget_update_vruler (SPDesktopWidget *dtw) -{ - /* The viewbox (in integers) must exactly match the size of SPCanvasbuf's pixel buffer. - * This is important because the former is being used for drawing the ruler, whereas - * the latter is used for drawing e.g. the grids and guides. Only when the viewbox - * coincides with the pixel buffer, everything will line up nicely. - */ - Geom::IntRect viewbox = dtw->canvas->getViewboxIntegers(); - gdouble position; + double lower_x = dtw->dt2r * (viewbox.left() - dtw->ruler_origin[Geom::X]); + double upper_x = dtw->dt2r * (viewbox.right() - dtw->ruler_origin[Geom::X]); + sp_ruler_set_range(SP_RULER(dtw->hruler), + lower_x, + upper_x, + (upper_x - lower_x)); - double const scale = dtw->desktop->current_zoom(); - double s = viewbox.min()[Geom::Y] / -scale - dtw->ruler_origin[Geom::Y]; - double e = viewbox.max()[Geom::Y] / -scale - dtw->ruler_origin[Geom::Y]; - sp_ruler_get_range(SP_RULER(dtw->vruler), NULL, NULL, &position, NULL); - sp_ruler_set_range(SP_RULER(dtw->vruler), s, e, position, (e - s)); + double lower_y = dtw->dt2r * (viewbox.bottom() - dtw->ruler_origin[Geom::Y]); + double upper_y = dtw->dt2r * (viewbox.top() - dtw->ruler_origin[Geom::Y]); + sp_ruler_set_range(SP_RULER(dtw->vruler), + lower_y, + upper_y, + (upper_y - lower_y)); } @@ -1645,8 +1748,8 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) this->dt2r = 1.0 / nv->doc_units->unittobase; this->ruler_origin = Geom::Point(0,0); //nv->gridorigin; Why was the grid origin used here? - sp_ruler_set_metric(SP_RULER (this->vruler), nv->getDefaultMetric()); - sp_ruler_set_metric(SP_RULER (this->hruler), nv->getDefaultMetric()); + sp_ruler_set_unit(SP_RULER (this->vruler), nv->getDefaultMetric()); + sp_ruler_set_unit(SP_RULER (this->hruler), nv->getDefaultMetric()); /* This loops through all the grandchildren of aux toolbox, * and for each that it finds, it performs an sp_search_by_data_recursive(), diff --git a/src/widgets/desktop-widget.h b/src/widgets/desktop-widget.h index 73194304f..9188838b3 100644 --- a/src/widgets/desktop-widget.h +++ b/src/widgets/desktop-widget.h @@ -25,7 +25,7 @@ typedef struct _EgeColorProfTracker EgeColorProfTracker; struct SPCanvas; class SPDesktop; -class SPDesktopWidget; +struct SPDesktopWidget; class SPObject; @@ -105,7 +105,11 @@ struct SPDesktopWidget { unsigned int _interaction_disabled_counter; - SPCanvas *canvas; + SPCanvas *canvas; + + /** A table for displaying the canvas, rulers etc */ + GtkWidget *canvas_tbl; + Geom::Point ruler_origin; double dt2r; @@ -168,8 +172,6 @@ struct SPDesktopWidget { { sp_dtw_desktop_activate (_dtw); } virtual void deactivateDesktop() { sp_dtw_desktop_deactivate (_dtw); } - virtual void viewSetPosition (Geom::Point p) - { _dtw->viewSetPosition (p); } virtual void updateRulers() { sp_desktop_widget_update_rulers (_dtw); } virtual void updateScrollbars (double scale) diff --git a/src/widgets/dropper-toolbar.cpp b/src/widgets/dropper-toolbar.cpp index 8eeebf5c1..cf58aa507 100644 --- a/src/widgets/dropper-toolbar.cpp +++ b/src/widgets/dropper-toolbar.cpp @@ -28,9 +28,8 @@ # include "config.h" #endif -#include <glibmm/i18n.h> - #include "ui/widget/spinbutton.h" +#include <glibmm/i18n.h> #include "toolbox.h" #include "dropper-toolbar.h" diff --git a/src/widgets/dropper-toolbar.h b/src/widgets/dropper-toolbar.h index eee50ae5c..aa2116daf 100644 --- a/src/widgets/dropper-toolbar.h +++ b/src/widgets/dropper-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_dropper_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/eek-preview.cpp b/src/widgets/eek-preview.cpp index 595c289f2..988aa2453 100644 --- a/src/widgets/eek-preview.cpp +++ b/src/widgets/eek-preview.cpp @@ -42,71 +42,83 @@ using std::min; #include <gtk/gtk.h> #include "eek-preview.h" +#include "preferences.h" #define PRIME_BUTTON_MAGIC_NUMBER 1 -#define FOCUS_PROP_ID 1 - -/* Keep in sycn with last value in eek-preview.h */ +/* Keep in sync with last value in eek-preview.h */ #define PREVIEW_SIZE_LAST PREVIEW_SIZE_HUGE #define PREVIEW_SIZE_NEXTFREE (PREVIEW_SIZE_HUGE + 1) #define PREVIEW_MAX_RATIO 500 -static void eek_preview_class_init( EekPreviewClass *klass ); -static void eek_preview_init( EekPreview *preview ); +enum { + PROP_0, + PROP_FOCUS +}; + +typedef struct +{ + int scaledW; + int scaledH; + + int r; + int g; + int b; + + gboolean hot; + gboolean within; + gboolean takesFocus; + ViewType view; + PreviewSize size; + guint ratio; + guint linked; + guint border; + GdkPixbuf *previewPixbuf; + GdkPixbuf *scaled; +} EekPreviewPrivate; + +#define EEK_PREVIEW_GET_PRIVATE(preview) \ + G_TYPE_INSTANCE_GET_PRIVATE(preview, EEK_PREVIEW_TYPE, EekPreviewPrivate) + +static void eek_preview_class_init( EekPreviewClass *klass ); +static void eek_preview_init( EekPreview *preview ); static gboolean eek_preview_draw(GtkWidget* widget, cairo_t* cr); +G_DEFINE_TYPE(EekPreview, eek_preview, GTK_TYPE_DRAWING_AREA); + static GtkWidgetClass* parent_class = 0; void eek_preview_set_color( EekPreview* preview, int r, int g, int b ) { - preview->_r = r; - preview->_g = g; - preview->_b = b; + EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); + + priv->r = r; + priv->g = g; + priv->b = b; gtk_widget_queue_draw(GTK_WIDGET(preview)); } -void eek_preview_set_pixbuf( EekPreview* preview, GdkPixbuf* pixbuf ) +void +eek_preview_set_pixbuf(EekPreview *preview, + GdkPixbuf *pixbuf) { - preview->_previewPixbuf = pixbuf; + EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); - gtk_widget_queue_draw(GTK_WIDGET(preview)); - - if (preview->_scaled) { - g_object_unref(preview->_scaled); - preview->_scaled = 0; - } - preview->_scaledW = gdk_pixbuf_get_width(preview->_previewPixbuf); - preview->_scaledH = gdk_pixbuf_get_height(preview->_previewPixbuf); -} + priv->previewPixbuf = pixbuf; + gtk_widget_queue_draw(GTK_WIDGET(preview)); -GType eek_preview_get_type(void) -{ - static GType preview_type = 0; - - if (!preview_type) { - static const GTypeInfo preview_info = { - sizeof( EekPreviewClass ), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)eek_preview_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof( EekPreview ), - 0, /* n_preallocs */ - (GInstanceInitFunc)eek_preview_init, - NULL /* value_table */ - }; - - - preview_type = g_type_register_static( GTK_TYPE_DRAWING_AREA, "EekPreview", &preview_info, (GTypeFlags)0 ); + if (priv->scaled) + { + g_object_unref(priv->scaled); + priv->scaled = NULL; } - return preview_type; + priv->scaledW = gdk_pixbuf_get_width(priv->previewPixbuf); + priv->scaledH = gdk_pixbuf_get_height(priv->previewPixbuf); } static gboolean setupDone = FALSE; @@ -148,9 +160,10 @@ void eek_preview_set_size_mappings( guint count, GtkIconSize const* sizes ) static void eek_preview_size_request( GtkWidget* widget, GtkRequisition* req ) { - gint width = 0; - gint height = 0; - EekPreview* preview = EEK_PREVIEW(widget); + gint width = 0; + gint height = 0; + EekPreview *preview = EEK_PREVIEW(widget); + EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); if ( !setupDone ) { GtkIconSize sizes[] = { @@ -163,15 +176,15 @@ static void eek_preview_size_request( GtkWidget* widget, GtkRequisition* req ) eek_preview_set_size_mappings( G_N_ELEMENTS(sizes), sizes ); } - width = sizeThings[preview->_size].width; - height = sizeThings[preview->_size].height; + width = sizeThings[priv->size].width; + height = sizeThings[priv->size].height; - if ( preview->_view == VIEW_TYPE_LIST ) { + if ( priv->view == VIEW_TYPE_LIST ) { width *= 3; } - if ( preview->_ratio != 100 ) { - width = (width * preview->_ratio) / 100; + if ( priv->ratio != 100 ) { + width = (width * priv->ratio) / 100; if ( width < 0 ) { width = 1; } @@ -222,258 +235,306 @@ static gboolean eek_preview_expose_event( GtkWidget* widget, GdkEventExpose* /* } #endif -static gboolean eek_preview_draw(GtkWidget* widget, cairo_t* cr) +static +gboolean eek_preview_draw(GtkWidget *widget, + cairo_t *cr) { - GtkStyle* style = gtk_widget_get_style(widget); - GtkAllocation allocation; - gtk_widget_get_allocation (widget, &allocation); - EekPreview* preview = EEK_PREVIEW(widget); - GdkColor fg = {0, preview->_r, preview->_g, preview->_b}; - gint insetX = 0; - gint insetY = 0; + GtkStyle *style = gtk_widget_get_style(widget); + EekPreview *preview = EEK_PREVIEW(widget); + EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); + + GtkAllocation allocation; + gtk_widget_get_allocation(widget, &allocation); + + GdkColor fg = { 0, + static_cast<guint16>(priv->r), + static_cast<guint16>(priv->g), + static_cast<guint16>(priv->b) + }; + + gint insetTop = 0, insetBottom = 0; + gint insetLeft = 0, insetRight = 0; + + if (priv->border == BORDER_SOLID) { + insetTop = 1; + insetLeft = 1; + } + if (priv->border == BORDER_SOLID_LAST_ROW) { + insetTop = insetBottom = 1; + insetLeft = 1; + } + if (priv->border == BORDER_WIDE) { + insetTop = insetBottom = 1; + insetLeft = insetRight = 1; + } + #if GTK_CHECK_VERSION(3,0,0) - GtkStyleContext *context = gtk_widget_get_style_context(widget); + GtkStyleContext *context = gtk_widget_get_style_context(widget); - gtk_render_frame(context, - cr, - 0, 0, - allocation.width, allocation.height); + gtk_render_frame(context, + cr, + 0, 0, + allocation.width, allocation.height); - gtk_render_background(context, - cr, - 0, 0, - allocation.width, allocation.height); + gtk_render_background(context, + cr, + 0, 0, + allocation.width, allocation.height); #else - GdkWindow* window = gtk_widget_get_window(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); + 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 ); + gdk_colormap_alloc_color( gdk_colormap_get_system(), &fg, FALSE, TRUE ); #endif - GdkRectangle rect = {insetX, - insetY, - allocation.width - (insetX * 2), - allocation.height - (insetY * 2)}; + // Border + if (priv->border != BORDER_NONE) { + cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); + cairo_rectangle(cr, 0, 0, allocation.width, allocation.height); + cairo_fill(cr); + } - gdk_cairo_set_source_color(cr, &fg); - gdk_cairo_rectangle(cr, &rect); - cairo_paint(cr); + cairo_set_source_rgb(cr, priv->r/65535.0, priv->g/65535.0, priv->b/65535.0 ); + cairo_rectangle(cr, insetLeft, insetTop, allocation.width - (insetLeft + insetRight), allocation.height - (insetTop + insetBottom)); + cairo_fill(cr); - if ( preview->_previewPixbuf ) { - GtkDrawingArea *da = &(preview->drawing); - GdkWindow *da_window = gtk_widget_get_window(GTK_WIDGET(da)); - cairo_t *cr = gdk_cairo_create(da_window); + 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); -#if GTK_CHECK_VERSION(2,24,0) - gint w = gdk_window_get_width(da_window); - gint h = gdk_window_get_height(da_window); -#else - gint w = 0; - gint h = 0; - gdk_drawable_get_size(da_window, &w, &h); -#endif - - if ((w != preview->_scaledW) || (h != preview->_scaledH)) { - if (preview->_scaled) { - g_object_unref(preview->_scaled); - } - preview->_scaled = gdk_pixbuf_scale_simple(preview->_previewPixbuf, w, h, GDK_INTERP_BILINEAR); - preview->_scaledW = w; - preview->_scaledH = h; + gint w = gdk_window_get_width(da_window); + gint h = gdk_window_get_height(da_window); + + if ((w != priv->scaledW) || (h != priv->scaledH)) { + if (priv->scaled) + { + g_object_unref(priv->scaled); } - GdkPixbuf *pix = (preview->_scaled) ? preview->_scaled : preview->_previewPixbuf; - gdk_cairo_set_source_pixbuf(cr, pix, 0, 0); - cairo_paint(cr); - cairo_destroy(cr); + priv->scaled = gdk_pixbuf_scale_simple(priv->previewPixbuf, + w - (insetLeft + insetRight), + h - (insetTop + insetBottom), + GDK_INTERP_BILINEAR); + + priv->scaledW = w - (insetLeft + insetRight); + priv->scaledH = h - (insetTop + insetBottom); } - if ( preview->_linked ) { - /* Draw arrow */ - GdkRectangle possible = {insetX, insetY, (allocation.width - (insetX * 2)), (allocation.height - (insetY * 2)) }; - GdkRectangle area = {possible.x, possible.y, possible.width / 2, possible.height / 2 }; - - /* Make it square */ - if ( area.width > area.height ) - area.width = area.height; - if ( area.height > area.width ) - area.height = area.width; - - /* Center it horizontally */ - if ( area.width < possible.width ) { - int diff = (possible.width - area.width) / 2; - area.x += diff; - } + GdkPixbuf *pix = (priv->scaled) ? priv->scaled : priv->previewPixbuf; + // Border + if (priv->border != BORDER_NONE) { + cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); + cairo_rectangle(cr, 0, 0, allocation.width, allocation.height); + cairo_fill(cr); + } - if ( preview->_linked & PREVIEW_LINK_IN ) { + gdk_cairo_set_source_pixbuf(cr, pix, insetLeft, insetTop); + cairo_paint(cr); + cairo_destroy(cr); + } + + if (priv->linked) + { + /* Draw arrow */ + GdkRectangle possible = {insetLeft, + insetTop, + (allocation.width - (insetLeft + insetRight)), + (allocation.height - (insetTop + insetBottom)) + }; + + GdkRectangle area = {possible.x, + possible.y, + possible.width / 2, + possible.height / 2 }; + + /* Make it square */ + if ( area.width > area.height ) + area.width = area.height; + if ( area.height > area.width ) + area.height = area.width; + + /* Center it horizontally */ + if ( area.width < possible.width ) { + int diff = (possible.width - area.width) / 2; + area.x += diff; + } + + 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) - ); + 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 - ); + 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 ( preview->_linked & PREVIEW_LINK_OUT ) { - GdkRectangle otherArea = {area.x, area.y, area.width, area.height}; - if ( otherArea.height < possible.height ) { - otherArea.y = possible.y + (possible.height - otherArea.height); - } + if (priv->linked & PREVIEW_LINK_OUT) + { + GdkRectangle otherArea = {area.x, area.y, area.width, area.height}; + if ( otherArea.height < possible.height ) { + 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) - ); + 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 - ); + 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 ( preview->_linked & PREVIEW_LINK_OTHER ) { - GdkRectangle otherArea = {insetX, area.y, area.width, area.height}; - if ( otherArea.height < possible.height ) { - otherArea.y = possible.y + (possible.height - otherArea.height) / 2; - } + if (priv->linked & PREVIEW_LINK_OTHER) + { + GdkRectangle otherArea = {insetLeft, area.y, area.width, area.height}; + if ( otherArea.height < possible.height ) { + 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) - ); + 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 - ); + 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 - } + } - if ( preview->_linked & PREVIEW_FILL ) { - GdkRectangle otherArea = {possible.x + ((possible.width / 4) - (area.width / 2)), - area.y, - area.width, area.height}; - if ( otherArea.height < possible.height ) { - otherArea.y = possible.y + (possible.height - otherArea.height) / 2; - } + if (priv->linked & PREVIEW_FILL) + { + GdkRectangle otherArea = {possible.x + ((possible.width / 4) - (area.width / 2)), + area.y, + area.width, area.height}; + 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 ); + 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 ); + 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 ( preview->_linked & PREVIEW_STROKE ) { - GdkRectangle otherArea = {possible.x + (((possible.width * 3) / 4) - (area.width / 2)), - area.y, - area.width, area.height}; - if ( otherArea.height < possible.height ) { - otherArea.y = possible.y + (possible.height - otherArea.height) / 2; - } + if (priv->linked & PREVIEW_STROKE) + { + GdkRectangle otherArea = {possible.x + (((possible.width * 3) / 4) - (area.width / 2)), + area.y, + area.width, area.height}; + if ( otherArea.height < possible.height ) { + otherArea.y = possible.y + (possible.height - otherArea.height) / 2; + } #if GTK_CHECK_VERSION(3,0,0) - gtk_paint_diamond( style, - cr, - gtk_widget_get_state (widget), - GTK_SHADOW_ETCHED_OUT, - widget, - NULL, - otherArea.x, otherArea.y, - otherArea.width, otherArea.height ); + gtk_paint_diamond( style, + cr, + gtk_widget_get_state (widget), + GTK_SHADOW_ETCHED_OUT, + widget, + NULL, + 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 ); + 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 - } } + } - if ( gtk_widget_has_focus(widget) ) { - gtk_widget_get_allocation (widget, &allocation); + 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 ); + 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 ); + 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; } @@ -482,51 +543,48 @@ static gboolean eek_preview_draw(GtkWidget* widget, cairo_t* cr) static gboolean eek_preview_enter_cb( GtkWidget* widget, GdkEventCrossing* event ) { if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) { - EekPreview* preview = EEK_PREVIEW(widget); - preview->_within = TRUE; - gtk_widget_set_state( widget, preview->_hot ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT ); + EekPreview *preview = EEK_PREVIEW(widget); + EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); + + priv->within = TRUE; + gtk_widget_set_state( widget, priv->hot ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT ); } + return FALSE; } static gboolean eek_preview_leave_cb( GtkWidget* widget, GdkEventCrossing* event ) { if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) { - EekPreview* preview = EEK_PREVIEW(widget); - preview->_within = FALSE; + EekPreview *preview = EEK_PREVIEW(widget); + EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); + + priv->within = FALSE; gtk_widget_set_state( widget, GTK_STATE_NORMAL ); } - return FALSE; -} -/* -static gboolean eek_preview_focus_in_event( GtkWidget* widget, GdkEventFocus* event ) -{ - g_message("focus IN"); - gboolean blip = parent_class->focus_in_event ? parent_class->focus_in_event(widget, event) : FALSE; - return blip; -} - -static gboolean eek_preview_focus_out_event( GtkWidget* widget, GdkEventFocus* event ) -{ - g_message("focus OUT"); - gboolean blip = parent_class->focus_out_event ? parent_class->focus_out_event(widget, event) : FALSE; - return blip; + return FALSE; } -*/ static gboolean eek_preview_button_press_cb( GtkWidget* widget, GdkEventButton* event ) { - if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) { - EekPreview* preview = EEK_PREVIEW(widget); + if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) + { + EekPreview *preview = EEK_PREVIEW(widget); + EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); - if ( preview->_takesFocus && !gtk_widget_has_focus(widget) ) { + if ( priv->takesFocus && !gtk_widget_has_focus(widget) ) + { gtk_widget_grab_focus(widget); } - if ( event->button == PRIME_BUTTON_MAGIC_NUMBER ) { - preview->_hot = TRUE; - if ( preview->_within ) { + if ( event->button == PRIME_BUTTON_MAGIC_NUMBER || + event->button == 2 ) + { + priv->hot = TRUE; + + if ( priv->within ) + { gtk_widget_set_state( widget, GTK_STATE_ACTIVE ); } } @@ -538,89 +596,76 @@ static gboolean eek_preview_button_press_cb( GtkWidget* widget, GdkEventButton* static gboolean eek_preview_button_release_cb( GtkWidget* widget, GdkEventButton* event ) { if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) { - EekPreview* preview = EEK_PREVIEW(widget); - preview->_hot = FALSE; + EekPreview *preview = EEK_PREVIEW(widget); + EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); + + priv->hot = FALSE; gtk_widget_set_state( widget, GTK_STATE_NORMAL ); - if ( preview->_within && event->button == PRIME_BUTTON_MAGIC_NUMBER ) { - gboolean isAlt = (event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK; - if ( isAlt ) { + if ( priv->within && + (event->button == PRIME_BUTTON_MAGIC_NUMBER || + event->button == 2)) + { + gboolean isAlt = ( ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) || + (event->button == 2)); + + if ( isAlt ) + { g_signal_emit( widget, eek_preview_signals[ALTCLICKED_SIGNAL], 0, 2 ); - } else { + } + else + { g_signal_emit( widget, eek_preview_signals[CLICKED_SIGNAL], 0 ); } } } - return FALSE; -} - -gboolean eek_preview_key_press_event( GtkWidget* widget, GdkEventKey* event) -{ - (void)widget; - (void)event; - g_message("TICK"); - return FALSE; -} -gboolean eek_preview_key_release_event( GtkWidget* widget, GdkEventKey* event) -{ - (void)widget; - (void)event; - g_message("tock"); return FALSE; } -static void eek_preview_get_property( GObject *object, - guint property_id, - GValue *value, +static void eek_preview_get_property( GObject *object, + guint prop_id, + GValue *value, GParamSpec *pspec) { - GObjectClass* gobjClass = G_OBJECT_CLASS(parent_class); - switch ( property_id ) { - case FOCUS_PROP_ID: - { - EekPreview* preview = EEK_PREVIEW( object ); - g_value_set_boolean( value, preview->_takesFocus ); - } - break; + EekPreview *preview = EEK_PREVIEW( object ); + EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); + + switch (prop_id) + { + case PROP_FOCUS: + g_value_set_boolean( value, priv->takesFocus ); + break; + default: - { - if ( gobjClass->get_property ) { - gobjClass->get_property( object, property_id, value, pspec ); - } - } + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; } } -static void eek_preview_set_property( GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) +static void +eek_preview_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - GObjectClass* gobjClass = G_OBJECT_CLASS(parent_class); - switch ( property_id ) { - case FOCUS_PROP_ID: - { - EekPreview* preview = EEK_PREVIEW( object ); - gboolean val = g_value_get_boolean( value ); - if ( val != preview->_takesFocus ) { - preview->_takesFocus = val; - } - } - break; + EekPreview *preview = EEK_PREVIEW( object ); + + switch (prop_id) + { + case PROP_FOCUS: + eek_preview_set_focus_on_click(preview, g_value_get_boolean(value)); + break; + default: - { - if ( gobjClass->set_property ) { - gobjClass->set_property( object, property_id, value, pspec ); - } - } + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; } } static gboolean eek_preview_popup_menu( GtkWidget* widget ) { -/* g_message("Do the popup!"); */ gboolean blip = parent_class->popup_menu ? parent_class->popup_menu(widget) : FALSE; return blip; } @@ -628,21 +673,14 @@ static gboolean eek_preview_popup_menu( GtkWidget* widget ) static void eek_preview_class_init( EekPreviewClass *klass ) { - GObjectClass* gobjClass = G_OBJECT_CLASS(klass); - /*GtkObjectClass* objectClass = (GtkObjectClass*)klass;*/ + GObjectClass* gobjClass = G_OBJECT_CLASS(klass); GtkWidgetClass* widgetClass = (GtkWidgetClass*)klass; gobjClass->set_property = eek_preview_set_property; gobjClass->get_property = eek_preview_get_property; - /*objectClass->destroy = eek_preview_destroy;*/ - parent_class = (GtkWidgetClass*)g_type_class_peek_parent( klass ); - /*widgetClass->map = ;*/ - /*widgetClass->unmap = ;*/ - /*widgetClass->realize = ;*/ - /*widgetClass->unrealize = ;*/ #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; @@ -651,49 +689,16 @@ static void eek_preview_class_init( EekPreviewClass *klass ) widgetClass->size_request = eek_preview_size_request; widgetClass->expose_event = eek_preview_expose_event; #endif - /*widgetClass->size_allocate = ;*/ - /*widgetClass->state_changed = ;*/ - /*widgetClass->style_set = ;*/ - /*widgetClass->grab_notify = ;*/ widgetClass->button_press_event = eek_preview_button_press_cb; widgetClass->button_release_event = eek_preview_button_release_cb; - /*widgetClass->delete_event = ;*/ - /*widgetClass->destroy_event = ;*/ -/* widgetClass->key_press_event = eek_preview_key_press_event; */ -/* widgetClass->key_release_event = eek_preview_key_release_event; */ widgetClass->enter_notify_event = eek_preview_enter_cb; widgetClass->leave_notify_event = eek_preview_leave_cb; - /*widgetClass->configure_event = ;*/ - /*widgetClass->focus_in_event = eek_preview_focus_in_event;*/ - /*widgetClass->focus_out_event = eek_preview_focus_out_event;*/ - - /* selection */ - /*widgetClass->selection_get = ;*/ - /*widgetClass->selection_received = ;*/ - - - /* drag source: */ - /*widgetClass->drag_begin = ;*/ - /*widgetClass->drag_end = ;*/ - /*widgetClass->drag_data_get = ;*/ - /*widgetClass->drag_data_delete = ;*/ - - /* drag target: */ - /*widgetClass->drag_leave = ;*/ - /*widgetClass->drag_motion = ;*/ - /*widgetClass->drag_drop = ;*/ - /*widgetClass->drag_data_received = ;*/ /* For keybindings: */ widgetClass->popup_menu = eek_preview_popup_menu; - /*widgetClass->show_help = ;*/ - - /* Accessibility support: */ - /*widgetClass->get_accessible = ;*/ - /*widgetClass->screen_changed = ;*/ - /*widgetClass->can_activate_accel = ;*/ + g_type_class_add_private(gobjClass, sizeof(EekPreviewPrivate)); eek_preview_signals[CLICKED_SIGNAL] = g_signal_new( "clicked", @@ -714,7 +719,7 @@ static void eek_preview_class_init( EekPreviewClass *klass ) g_object_class_install_property( gobjClass, - FOCUS_PROP_ID, + PROP_FOCUS, g_param_spec_boolean( "focus-on-click", NULL, @@ -722,57 +727,94 @@ static void eek_preview_class_init( EekPreviewClass *klass ) TRUE, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_CONSTRUCT) ) - ); + ); } -void eek_preview_set_linked( EekPreview* splat, LinkType link ) +void +eek_preview_set_linked(EekPreview *preview, + LinkType link) { + EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); + + g_return_if_fail(IS_EEK_PREVIEW(preview)); + link = (LinkType)(link & PREVIEW_LINK_ALL); - if ( link != (LinkType)splat->_linked ) { - splat->_linked = link; - gtk_widget_queue_draw( GTK_WIDGET(splat) ); + if (link != (LinkType)priv->linked) + { + priv->linked = link; + + gtk_widget_queue_draw(GTK_WIDGET(preview)); } } -LinkType eek_preview_get_linked( EekPreview* splat ) +LinkType +eek_preview_get_linked(EekPreview *preview) { - return (LinkType)splat->_linked; + g_return_val_if_fail(IS_EEK_PREVIEW(preview), PREVIEW_LINK_NONE); + + return (LinkType)EEK_PREVIEW_GET_PRIVATE(preview)->linked; } -gboolean eek_preview_get_focus_on_click( EekPreview* preview ) +gboolean +eek_preview_get_focus_on_click(EekPreview* preview) { - return preview->_takesFocus; + g_return_val_if_fail(IS_EEK_PREVIEW(preview), FALSE); + + return EEK_PREVIEW_GET_PRIVATE(preview)->takesFocus; } -void eek_preview_set_focus_on_click( EekPreview* preview, gboolean focus_on_click ) +void +eek_preview_set_focus_on_click(EekPreview *preview, + gboolean focus_on_click) { - if ( focus_on_click != preview->_takesFocus ) { - preview->_takesFocus = focus_on_click; + EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); + + g_return_if_fail(IS_EEK_PREVIEW(preview)); + + if (focus_on_click != priv->takesFocus) + { + priv->takesFocus = focus_on_click; } } -void eek_preview_set_details( EekPreview* preview, PreviewStyle prevstyle, ViewType view, PreviewSize size, guint ratio ) +void +eek_preview_set_details(EekPreview *preview, + ViewType view, + PreviewSize size, + guint ratio, + guint border) { - preview->_prevstyle = prevstyle; - preview->_view = view; + EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); + + g_return_if_fail(IS_EEK_PREVIEW(preview)); + + priv->view = view; - if ( size > PREVIEW_SIZE_LAST ) { + if ( size > PREVIEW_SIZE_LAST ) + { size = PREVIEW_SIZE_LAST; } - preview->_size = size; - if ( ratio > PREVIEW_MAX_RATIO ) { + priv->size = size; + + if ( ratio > PREVIEW_MAX_RATIO ) + { ratio = PREVIEW_MAX_RATIO; } - preview->_ratio = ratio; + + priv->ratio = ratio; + priv->border = border; gtk_widget_queue_draw(GTK_WIDGET(preview)); } -static void eek_preview_init( EekPreview *preview ) +static void +eek_preview_init(EekPreview *preview) { - GtkWidget* widg = GTK_WIDGET(preview); + GtkWidget *widg = GTK_WIDGET(preview); + EekPreviewPrivate *priv = EEK_PREVIEW_GET_PRIVATE(preview); + gtk_widget_set_can_focus( widg, TRUE ); gtk_widget_set_receives_default( widg, TRUE ); @@ -786,69 +828,22 @@ static void eek_preview_init( EekPreview *preview ) | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK ); -/* gtk_widget_add_events( widg, GDK_ALL_EVENTS_MASK );*/ - - preview->_r = 0x80; - preview->_g = 0x80; - preview->_b = 0xcc; - preview->_scaledW = 0; - preview->_scaledH = 0; - - preview->_hot = FALSE; - preview->_within = FALSE; - preview->_takesFocus = FALSE; - - preview->_prevstyle = PREVIEW_STYLE_ICON; - preview->_view = VIEW_TYPE_LIST; - preview->_size = PREVIEW_SIZE_SMALL; - preview->_ratio = 100; - - preview->_previewPixbuf = 0; - preview->_scaled = 0; - -/* - GdkColor color = {0}; - color.red = (255 << 8) | 255; - - GdkColor whack = {0}; - whack.green = (255 << 8) | 255; - - gtk_widget_modify_bg( widg, GTK_STATE_NORMAL, &color ); - gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &whack ); -*/ - -/* GTK_STATE_ACTIVE, */ -/* GTK_STATE_PRELIGHT, */ -/* GTK_STATE_SELECTED, */ -/* GTK_STATE_INSENSITIVE */ - - if ( 0 ) { - GdkColor color = {0,0,0,0}; - - color.red = 0xffff; - color.green = 0; - color.blue = 0xffff; -#if !GTK_CHECK_VERSION(3,0,0) - gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE ); -#endif - gtk_widget_modify_bg(widg, GTK_STATE_ACTIVE, &color); - - color.red = 0; - color.green = 0xffff; - color.blue = 0; -#if !GTK_CHECK_VERSION(3,0,0) - gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE ); -#endif - gtk_widget_modify_bg(widg, GTK_STATE_SELECTED, &color); - - color.red = 0xffff; - color.green = 0; - color.blue = 0; -#if !GTK_CHECK_VERSION(3,0,0) - gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE ); -#endif - gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &color ); - } + priv->r = 0x80; + priv->g = 0x80; + priv->b = 0xcc; + priv->scaledW = 0; + priv->scaledH = 0; + + priv->hot = FALSE; + priv->within = FALSE; + priv->takesFocus = FALSE; + + priv->view = VIEW_TYPE_LIST; + priv->size = PREVIEW_SIZE_SMALL; + priv->ratio = 100; + priv->border = BORDER_NONE; + priv->previewPixbuf = 0; + priv->scaled = 0; } diff --git a/src/widgets/eek-preview.h b/src/widgets/eek-preview.h index 7275ab9b4..e4c724cc5 100644 --- a/src/widgets/eek-preview.h +++ b/src/widgets/eek-preview.h @@ -42,12 +42,11 @@ /** * @file - * Generic implementation of a object that can be shown by a preview. + * Generic implementation of an object that can be shown by a preview. */ G_BEGIN_DECLS - #define EEK_PREVIEW_TYPE (eek_preview_get_type()) #define EEK_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST( (obj), EEK_PREVIEW_TYPE, EekPreview)) #define EEK_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST( (klass), EEK_PREVIEW_TYPE, EekPreviewClass)) @@ -90,31 +89,19 @@ typedef enum { PREVIEW_LINK_ALL = 31 } LinkType; +typedef enum { + BORDER_NONE = 0, + BORDER_SOLID, + BORDER_WIDE, + BORDER_SOLID_LAST_ROW, +} BorderStyle; + typedef struct _EekPreview EekPreview; typedef struct _EekPreviewClass EekPreviewClass; - struct _EekPreview { GtkDrawingArea drawing; - - int _r; - int _g; - int _b; - int _scaledW; - int _scaledH; - - gboolean _hot; - gboolean _within; - gboolean _takesFocus; - - PreviewStyle _prevstyle; - ViewType _view; - PreviewSize _size; - guint _ratio; - guint _linked; - GdkPixbuf* _previewPixbuf; - GdkPixbuf* _scaled; }; struct _EekPreviewClass @@ -124,11 +111,14 @@ struct _EekPreviewClass void (*clicked) (EekPreview* splat); }; - GType eek_preview_get_type(void) G_GNUC_CONST; GtkWidget* eek_preview_new(void); -void eek_preview_set_details( EekPreview* splat, PreviewStyle prevstyle, ViewType view, PreviewSize size, guint ratio ); +void eek_preview_set_details(EekPreview *preview, + ViewType view, + PreviewSize size, + guint ratio, + guint border); void eek_preview_set_color( EekPreview* splat, int r, int g, int b ); void eek_preview_set_pixbuf( EekPreview* splat, GdkPixbuf* pixbuf ); diff --git a/src/widgets/erasor-toolbar.cpp b/src/widgets/erasor-toolbar.cpp index 740af6821..2e074490d 100644 --- a/src/widgets/erasor-toolbar.cpp +++ b/src/widgets/erasor-toolbar.cpp @@ -28,10 +28,8 @@ # include "config.h" #endif - -#include <glibmm/i18n.h> - #include "ui/widget/spinbutton.h" +#include <glibmm/i18n.h> #include "toolbox.h" #include "erasor-toolbar.h" #include "calligraphy-toolbar.h" @@ -82,7 +80,7 @@ static void sp_erc_width_value_changed( GtkAdjustment *adj, GObject *tbl ) static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); bool eraserMode = ege_select_one_action_get_active( act ) != 0; if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -94,9 +92,11 @@ static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) // in turn, prevent listener from responding g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + /* if ( eraserMode != 0 ) { } else { } + */ // TODO finish implementation g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); diff --git a/src/widgets/erasor-toolbar.h b/src/widgets/erasor-toolbar.h index f00ceebe4..b1bb3a3fa 100644 --- a/src/widgets/erasor-toolbar.h +++ b/src/widgets/erasor-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp index 32619de1f..60e115f54 100644 --- a/src/widgets/fill-style.cpp +++ b/src/widgets/fill-style.cpp @@ -22,8 +22,8 @@ # include "config.h" #endif -#include <glibmm/i18n.h> #include <gtkmm/box.h> +#include <glibmm/i18n.h> #include "verbs.h" @@ -220,7 +220,7 @@ void FillNStroke::setDesktop(SPDesktop *desktop) * Listen to this "change in tool" event, in case a subselection tool (such as Gradient or Node) selection * is changed back to a selection tool - especially needed for selected gradient stops. */ -void FillNStroke::eventContextCB(SPDesktop *desktop, SPEventContext *eventcontext) +void FillNStroke::eventContextCB(SPDesktop * /*desktop*/, SPEventContext * /*eventcontext*/) { performUpdate(); } diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index 0244621bf..453ef683f 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -8,10 +8,11 @@ * Lauris Kaplinski <lauris@kaplinski.com> * bulia byak <buliabyak@users.sf.net> * Johan Engelen <j.b.c.engelen@ewi.utwente.nl> + * Tavmjong Bah <tavmjong@free.fr> * * Copyright (C) 1999-2001 Ximian, Inc. * Copyright (C) 2002 Lauris Kaplinski - * Copyright (C) -2007 Authors + * Copyright (C) -2013 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -51,11 +52,9 @@ struct SPFontSelector NRNameList families; NRStyleList styles; - int familyidx; - int styleidx; gfloat fontsize; bool fontsize_dirty; - font_instance *font; + Glib::ustring *fontspec; }; @@ -63,7 +62,7 @@ struct SPFontSelectorClass { GtkHBoxClass parent_class; - void (* font_set) (SPFontSelector *fsel, font_instance *font); + void (* font_set) (SPFontSelector *fsel, gchar *fontspec); }; enum { @@ -113,7 +112,7 @@ GType sp_font_selector_get_type() static void sp_font_selector_class_init(SPFontSelectorClass *c) { - GObjectClass *object_class = (GObjectClass *) c; + GObjectClass *object_class = G_OBJECT_CLASS(c); fs_parent_class = (GtkHBoxClass* )g_type_class_peek_parent (c); @@ -129,15 +128,18 @@ static void sp_font_selector_class_init(SPFontSelectorClass *c) object_class->dispose = sp_font_selector_dispose; } -void sp_font_selector_set_size_tooltip(SPFontSelector *fsel) +static void sp_font_selector_set_size_tooltip(SPFontSelector *fsel) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); - Glib::ustring tooltip = Glib::ustring::format("Font size (", sp_style_get_css_unit_string(unit), ")"); + Glib::ustring tooltip = Glib::ustring::format(_("Font size"), " (", sp_style_get_css_unit_string(unit), ")"); gtk_widget_set_tooltip_text (fsel->size, _(tooltip.c_str())); } +/* + * Create a widget with children for selecting font-family, font-style, and font-size. + */ static void sp_font_selector_init(SPFontSelector *fsel) { gtk_box_set_homogeneous(GTK_BOX(fsel), TRUE); @@ -155,15 +157,27 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(f), sw); - Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - fsel->family_treeview = gtk_tree_view_new (); 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_attributes (column, cell, "text", 0, NULL); + gtk_tree_view_column_set_cell_data_func (column, cell, + GtkTreeCellDataFunc (font_lister_cell_data_func), + NULL, NULL ); gtk_tree_view_append_column (GTK_TREE_VIEW(fsel->family_treeview), column); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(fsel->family_treeview), FALSE); + gtk_tree_view_set_row_separator_func( GTK_TREE_VIEW(fsel->family_treeview), + GtkTreeViewRowSeparatorFunc ((gpointer)font_lister_separator_func), + NULL, NULL ); + + /* Muck with style, see text-toolbar.cpp */ + gtk_widget_set_name( GTK_WIDGET(fsel->family_treeview), "font_selector_family" ); + gtk_rc_parse_string ( + "widget \"*font_selector_family\" style \"fontfamily-separator-style\""); + + + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); Glib::RefPtr<Gtk::ListStore> store = fontlister->get_font_list(); gtk_tree_view_set_model (GTK_TREE_VIEW(fsel->family_treeview), GTK_TREE_MODEL (Glib::unwrap (store))); gtk_container_add(GTK_CONTAINER(sw), fsel->family_treeview); @@ -218,16 +232,8 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_widget_show(hb); gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, FALSE, 0); -/* -This would introduce dependency on gtk version 2.24 which is currently not available in -Trisquel GNU/Linux 4.5.1 (released on May 25th, 2011) -This conditional and its #else block can be deleted in the future. -*/ -#if GTK_CHECK_VERSION(2, 24,0) + // Font-size fsel->size = gtk_combo_box_text_new_with_entry (); -#else - fsel->size = gtk_combo_box_entry_new_text (); -#endif sp_font_selector_set_size_tooltip(fsel); gtk_widget_set_size_request(fsel->size, 90, -1); @@ -242,20 +248,20 @@ This conditional and its #else block can be deleted in the future. gtk_widget_show_all (fsel->size); - fsel->familyidx = 0; - fsel->styleidx = 0; - fsel->fontsize = 10.0; + // Set default size... next two lines must match + gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(fsel->size))), "18.0"); + fsel->fontsize = 18.0; fsel->fontsize_dirty = false; - fsel->font = NULL; + + fsel->fontspec = new Glib::ustring; } static void sp_font_selector_dispose(GObject *object) { SPFontSelector *fsel = SP_FONT_SELECTOR (object); - if (fsel->font) { - fsel->font->Unref(); - fsel->font = NULL; + if (fsel->fontspec) { + delete fsel->fontspec; } if (fsel->families.length > 0) { @@ -273,49 +279,62 @@ static void sp_font_selector_dispose(GObject *object) } } +// Callback when family changed, updates style list for new family. static void sp_font_selector_family_select_row(GtkTreeSelection *selection, SPFontSelector *fsel) { - GtkTreeIter iter; - GtkTreeModel *model; - GtkListStore *store; - GtkTreePath *path; - GList *list=0; + // We need our own copy of the style list store since the font-family + // may not be the same in the font-selector as stored in the font-lister + // TODO: use font-lister class for this by modifying new_font_family to accept an optional style list + // TODO: add store to SPFontSelector struct and reuse. + + // Start by getting iterator to selected font + GtkTreeModel *model; + GtkTreeIter iter; if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; - path = gtk_tree_model_get_path (model, &iter); - gtk_tree_model_get (model, &iter, 1, &list, -1); - fsel->familyidx = gtk_tree_path_get_indices (path)[0]; - fsel->styleidx = 0; + // Next get family name with its style list + gchar *family; + GList *list=0; + gtk_tree_model_get (model, &iter, 0, &family, 1, &list, -1); - store = gtk_list_store_new (1, G_TYPE_STRING); + // Find best style match for selected family with current style (e.g. of selected text). + Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); + Glib::ustring style = fontlister->get_font_style(); + Glib::ustring best = fontlister->get_best_style_match (family, style); + // Create our own store of styles for selected font-family and find index of best style match + int path_index = 0; + int index = 0; + GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING); // Where is this deleted? for ( ; list ; list = list->next ) { gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, 0, (char*)list->data, -1); + + if( best.compare( (char*)list->data ) == 0 ) { + path_index = index; + } + ++index; } + // Attach store to tree view. Can trigger style changed signal (but not FONT_SET): gtk_tree_view_set_model (GTK_TREE_VIEW (fsel->style_treeview), GTK_TREE_MODEL (store)); - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, 0); + + // Get path to best style + GtkTreePath *path = gtk_tree_path_new (); + gtk_tree_path_append_index (path, path_index); + + // Highlight best style. Triggers style changed signal: gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path); gtk_tree_path_free (path); } +// Callback when row changed static void sp_font_selector_style_select_row (GtkTreeSelection *selection, SPFontSelector *fsel) { - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; - - path = gtk_tree_model_get_path (model, &iter); - fsel->styleidx = gtk_tree_path_get_indices (path)[0]; - if (!fsel->block_emit) { sp_font_selector_emit_set (fsel); @@ -325,6 +344,7 @@ static void sp_font_selector_style_select_row (GtkTreeSelection *selection, /* * Set the default list of font sizes, scaled to the users preferred unit + * TODO: This routine occurs both here and in text-toolbar. Move to font-lister? */ static void sp_font_selector_set_sizes( SPFontSelector *fsel ) { @@ -346,23 +366,16 @@ static void sp_font_selector_set_sizes( SPFontSelector *fsel ) { double size = sizes[n] / ratios[unit]; -#if GTK_CHECK_VERSION(2, 24,0) gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(fsel->size), Glib::ustring::format(size).c_str()); -#else - gtk_combo_box_append_text (GTK_COMBO_BOX(fsel->size), size); -#endif } } +// Callback when size changed static void sp_font_selector_size_changed( GtkComboBox */*cbox*/, SPFontSelector *fsel ) { char *text = NULL; -#if GTK_CHECK_VERSION(2, 24,0) text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (fsel->size)); -#else - text = gtk_combo_box_get_active_text (GTK_COMBO_BOX (fsel->size)); -#endif gfloat old_size = fsel->fontsize; gchar *endptr; @@ -392,9 +405,13 @@ static void sp_font_selector_size_changed( GtkComboBox */*cbox*/, SPFontSelector sp_font_selector_emit_set (fsel); } + +// Called from sp_font_selector_style_select_row +// Called from sp_font_selector_size_changed +// Called indirectly for sp_font_selector_family_select_row (since style changes). +// Emits FONT_SET signal (handled by TextEdit::onFontChange, GlyphsPanel::fontChangeCB). static void sp_font_selector_emit_set (SPFontSelector *fsel) { - font_instance *font; GtkTreeSelection *selection_family; GtkTreeSelection *selection_style; @@ -409,154 +426,83 @@ static void sp_font_selector_emit_set (SPFontSelector *fsel) model_family = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->family_treeview)); if (!model_family) return; - model_style = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->style_treeview)); - if (!model_style) return; + model_style = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->style_treeview)); + if (!model_style ) return; selection_family = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->family_treeview)); - selection_style = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)); + selection_style = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview )); if (!gtk_tree_selection_get_selected (selection_family, NULL, &iter_family)) return; - if (!gtk_tree_selection_get_selected (selection_style, NULL, &iter_style)) return; + if (!gtk_tree_selection_get_selected (selection_style, NULL, &iter_style )) return; gtk_tree_model_get (model_family, &iter_family, 0, &family, -1); - gtk_tree_model_get (model_style, &iter_style, 0, &style, -1); + gtk_tree_model_get (model_style, &iter_style, 0, &style, -1); if ((!family) || (!style)) return; - font = (font_factory::Default())->FaceFromUIStrings (family, style); + Glib::ustring fontspec = family; + fontspec += ", "; + fontspec += style; - // FIXME: when a text object uses non-available font, font==NULL and we can't set size - // (and the size shown in the widget is invalid). To fix, here we must always get some - // default font, exactly the same as sptext uses for on-canvas display, so that - // font!=NULL ever. - if (font != fsel->font || ( font && fsel->fontsize_dirty ) ) { - if ( font ) { - font->Ref(); - } - if ( fsel->font ) { - fsel->font->Unref(); - } - fsel->font = font; - g_signal_emit(fsel, fs_signals[FONT_SET], 0, fsel->font); - } - fsel->fontsize_dirty = false; - if (font) { - font->Unref(); - } - font = NULL; + *(fsel->fontspec) = fontspec; + + g_signal_emit(fsel, fs_signals[FONT_SET], 0, fontspec.c_str()); } GtkWidget *sp_font_selector_new() { - SPFontSelector *fsel = (SPFontSelector*) g_object_new(SP_TYPE_FONT_SELECTOR, NULL); + SPFontSelector *fsel = SP_FONT_SELECTOR(g_object_new(SP_TYPE_FONT_SELECTOR, NULL)); - return (GtkWidget *) fsel; + return GTK_WIDGET(fsel); } + /* - * Returns the index of the fonts closest style match from the provided list of styles - * Used in both the Text dialog and the Text toolbar to set the style combo on selection change + * Sets the values displayed in the font-selector from a fontspec. + * It is only called from TextEdit with a new selection and from GlyphsPanel */ -unsigned int sp_font_selector_get_best_style (font_instance *font, GList *list) +void sp_font_selector_set_fontspec (SPFontSelector *fsel, Glib::ustring fontspec, double size) { - font_instance *tempFont = NULL; - unsigned int currentStyleNumber = 0; - unsigned int bestStyleNumber = 0; - - Glib::ustring family = font_factory::Default()->GetUIFamilyString(font->descr); - - PangoFontDescription *incomingFont = pango_font_description_copy(font->descr); - pango_font_description_unset_fields(incomingFont, PANGO_FONT_MASK_SIZE); - - char *incomingFontString = pango_font_description_to_string(incomingFont); - - tempFont = (font_factory::Default())->FaceFromUIStrings(family.c_str(), (char*)list->data); - - PangoFontDescription *bestMatchForFont = NULL; - if (tempFont) { - bestMatchForFont = pango_font_description_copy(tempFont->descr); - tempFont->Unref(); - tempFont = NULL; - } - - pango_font_description_unset_fields(bestMatchForFont, PANGO_FONT_MASK_SIZE); - - list = list->next; - - while (list) { - currentStyleNumber++; - - tempFont = font_factory::Default()->FaceFromUIStrings(family.c_str(), (char*)list->data); - - PangoFontDescription *currentMatchForFont = NULL; - if (tempFont) { - currentMatchForFont = pango_font_description_copy(tempFont->descr); - tempFont->Unref(); - tempFont = NULL; - } - - if (currentMatchForFont) { - pango_font_description_unset_fields(currentMatchForFont, PANGO_FONT_MASK_SIZE); - - char *currentMatchString = pango_font_description_to_string(currentMatchForFont); - - if (!strcmp(incomingFontString, currentMatchString) - || pango_font_description_better_match(incomingFont, bestMatchForFont, currentMatchForFont)) { - // Found a better match for the font we are looking for - pango_font_description_free(bestMatchForFont); - bestMatchForFont = pango_font_description_copy(currentMatchForFont); - bestStyleNumber = currentStyleNumber; - } - - g_free(currentMatchString); - - pango_font_description_free(currentMatchForFont); - } - - list = list->next; - } + if (!fontspec.empty()) + { - if (bestMatchForFont) - pango_font_description_free(bestMatchForFont); - if (incomingFont) - pango_font_description_free(incomingFont); - g_free(incomingFontString); + Inkscape::FontLister *font_lister = Inkscape::FontLister::get_instance(); + std::pair<Glib::ustring, Glib::ustring> ui = font_lister->ui_from_fontspec( fontspec ); + Glib::ustring family = ui.first; + Glib::ustring style = ui.second; - return bestStyleNumber; -} - -void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, double size) -{ - if (font) - { Gtk::TreePath path; - - Glib::ustring family = font_factory::Default()->GetUIFamilyString(font->descr); - try { - path = Inkscape::FontLister::get_instance()->get_row_for_font (family); + path = font_lister->get_row_for_font (family); } catch (...) { + g_warning( "Couldn't find row for font-family: %s", family.c_str() ); return; } + // High light selected family and scroll so it is in view. fsel->block_emit = TRUE; gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->family_treeview)), path.gobj()); gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->family_treeview), path.gobj(), NULL, TRUE, 0.5, 0.5); - fsel->block_emit = FALSE; + fsel->block_emit = FALSE; // TODO: Should this be moved to the end? - GList *list = 0; - GtkTreeIter iter; - GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW(fsel->family_treeview)); - gtk_tree_model_get_iter (model, &iter, path.gobj()); - gtk_tree_model_get (model, &iter, 1, &list, -1); - unsigned int bestStyleNumber = sp_font_selector_get_best_style(font, list); + // We don't need to get best style since this is only called on a new + // selection where we already know the "best" style. + // Glib::ustring bestStyle = font_lister->get_best_style_match (family, style); + // std::cout << "Best: " << bestStyle << std::endl; + + // The "trial" style list and the regular list are the same in this case. + Gtk::TreePath path_c; + try { + path_c = font_lister->get_row_for_style( style ); + } catch (...) { + g_warning( "Couldn't find row for style: %s (%s)", style.c_str(), family.c_str() ); + return; + } + + gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path_c.gobj()); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->style_treeview), path_c.gobj(), NULL, TRUE, 0.5, 0.5); - GtkTreePath *path_c = gtk_tree_path_new (); - gtk_tree_path_append_index (path_c, bestStyleNumber); - gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path_c); - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->style_treeview), path_c, NULL, TRUE, 0.5, 0.5); - if (size != fsel->fontsize) { gchar s[8]; @@ -570,13 +516,9 @@ void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, doubl } -font_instance* sp_font_selector_get_font(SPFontSelector *fsel) +Glib::ustring sp_font_selector_get_fontspec(SPFontSelector *fsel) { - if (fsel->font) { - fsel->font->Ref(); - } - - return fsel->font; + return *(fsel->fontspec); } /* diff --git a/src/widgets/font-selector.h b/src/widgets/font-selector.h index 80e8b1e4d..66715f048 100644 --- a/src/widgets/font-selector.h +++ b/src/widgets/font-selector.h @@ -7,9 +7,11 @@ * Authors: * Chris Lahey <clahey@ximian.com> * Lauris Kaplinski <lauris@kaplinski.com> + * Tavmjong Bah <tavmjong@free.fr> * * Copyright (C) 1999-2001 Ximian, Inc. * Copyright (C) 2002 Lauris Kaplinski + * Copyright (C) 1999-2013 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -22,7 +24,24 @@ struct SPFontSelector; #define SP_FONT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_FONT_SELECTOR, SPFontSelector)) #define SP_IS_FONT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_FONT_SELECTOR)) -class font_instance; +/* + * The routines here create and manage a font selector widget with three parts, + * one each for font-family, font-style, and font-size. + * + * It is used by the TextEdit and Glyphs panel dialogs. The FontLister class is used + * to access the list of font-families and their associated styles for fonts either + * on the system or in the document. The FontLister class is also used by the Text + * toolbar. Fonts are kept track of by their "fontspecs" which are the same as the + * strings that Pango generates. + * + * The main functions are: + * Create the font-seletor widget. + * Update the lists when a new text selection is made. + * Update the Style list when a new font-family is selected, highlighting the + * best match to the original font style (as not all fonts have the same style options). + * Emit a signal when any change is made so that the Text Preview can be updated. + * Provide the currently selected values. + */ /* SPFontSelector */ @@ -30,13 +49,11 @@ GType sp_font_selector_get_type (void); GtkWidget *sp_font_selector_new (void); -void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, double size); +void sp_font_selector_set_fontspec (SPFontSelector *fsel, Glib::ustring fontspec, double size); +Glib::ustring sp_font_selector_get_fontspec (SPFontSelector *fsel); -font_instance *sp_font_selector_get_font (SPFontSelector *fsel); double sp_font_selector_get_size (SPFontSelector *fsel); -unsigned int sp_font_selector_get_best_style (font_instance *font, GList *list); - #endif // SP_FONT_SELECTOR_H /* diff --git a/src/widgets/gradient-image.cpp b/src/widgets/gradient-image.cpp index 3c84e606b..2d58355db 100644 --- a/src/widgets/gradient-image.cpp +++ b/src/widgets/gradient-image.cpp @@ -69,8 +69,8 @@ GType sp_gradient_image_get_type(void) static void sp_gradient_image_class_init(SPGradientImageClass *klass) { - GtkWidgetClass *widget_class = (GtkWidgetClass *) klass; - parent_class = (GtkWidgetClass*)g_type_class_peek_parent (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + parent_class = GTK_WIDGET_CLASS(g_type_class_peek_parent (klass)); #if GTK_CHECK_VERSION(3,0,0) // GObjectClass *object_class = G_OBJECT_CLASS(klass); @@ -80,7 +80,7 @@ static void sp_gradient_image_class_init(SPGradientImageClass *klass) widget_class->draw = sp_gradient_image_draw; widget_class->destroy = sp_gradient_image_destroy; #else - GtkObjectClass *object_class = (GtkObjectClass *) klass; + GtkObjectClass *object_class = GTK_OBJECT_CLASS(klass); object_class->destroy = sp_gradient_image_destroy; widget_class->size_request = sp_gradient_image_size_request; @@ -120,14 +120,14 @@ static void sp_gradient_image_destroy(GtkObject *object) if (parent_class->destroy) (* (parent_class)->destroy) (object); #else - if (((GtkObjectClass *) (parent_class))->destroy) - (* ((GtkObjectClass *) (parent_class))->destroy) (object); + if ((GTK_OBJECT_CLASS(parent_class))->destroy) + (* (GTK_OBJECT_CLASS(parent_class))->destroy) (object); #endif } static void sp_gradient_image_size_request(GtkWidget * /*widget*/, GtkRequisition *requisition) { - requisition->width = 64; + requisition->width = 54; requisition->height = 12; } @@ -192,13 +192,11 @@ static gboolean sp_gradient_image_draw(GtkWidget *widget, cairo_t *ct) GtkWidget * sp_gradient_image_new (SPGradient *gradient) { - SPGradientImage *image; - - image = (SPGradientImage*)g_object_new (SP_TYPE_GRADIENT_IMAGE, NULL); + SPGradientImage *image = SP_GRADIENT_IMAGE(g_object_new(SP_TYPE_GRADIENT_IMAGE, NULL)); sp_gradient_image_set_gradient (image, gradient); - return (GtkWidget *) image; + return GTK_WIDGET(image); } GdkPixbuf* diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index 3eba2da23..7a7f0d8ff 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -16,9 +16,11 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif +#include "gradient-vector.h" #include <gtk/gtk.h> #include "document.h" +#include "../document-undo.h" #include "../document-private.h" #include "../gradient-chemistry.h" #include "inkscape.h" @@ -29,7 +31,6 @@ #include <glibmm/i18n.h> #include <xml/repr.h> -#include "gradient-vector.h" #include "gradient-selector.h" #include "paint-selector.h" #include "style.h" @@ -52,6 +53,8 @@ static void sp_gradient_selector_dispose(GObject *object); static void sp_gradient_selector_vector_set (SPGradientVectorSelector *gvs, SPGradient *gr, SPGradientSelector *sel); static void sp_gradient_selector_edit_vector_clicked (GtkWidget *w, SPGradientSelector *sel); static void sp_gradient_selector_add_vector_clicked (GtkWidget *w, SPGradientSelector *sel); +static void sp_gradient_selector_delete_vector_clicked (GtkWidget *w, SPGradientSelector *sel); + static GtkVBoxClass *parent_class; static guint signals[LAST_SIGNAL] = {0}; @@ -83,9 +86,9 @@ GType sp_gradient_selector_get_type(void) static void sp_gradient_selector_class_init(SPGradientSelectorClass *klass) { - GObjectClass *object_class = (GObjectClass *) klass; + GObjectClass *object_class = G_OBJECT_CLASS(klass); - parent_class = (GtkVBoxClass*)g_type_class_peek_parent (klass); + parent_class = GTK_VBOX_CLASS(g_type_class_peek_parent (klass)); signals[GRABBED] = g_signal_new ("grabbed", G_TYPE_FROM_CLASS(object_class), @@ -124,6 +127,7 @@ static void sp_gradient_selector_init(SPGradientSelector *sel) sel->safelyInit = true; sel->blocked = false; new (&sel->nonsolid) std::vector<GtkWidget*>(); + new (&sel->swatch_widgets) std::vector<GtkWidget*>(); sel->mode = SPGradientSelector::MODE_LINEAR; @@ -143,17 +147,17 @@ static void sp_gradient_selector_init(SPGradientSelector *sel) sel->icon_renderer = Gtk::manage(new Gtk::CellRendererPixbuf()); sel->text_renderer = Gtk::manage(new Gtk::CellRendererText()); - sel->treeview->append_column("Gradient", *sel->icon_renderer); + sel->treeview->append_column(_("Gradient"), *sel->icon_renderer); Gtk::TreeView::Column* icon_column = sel->treeview->get_column(0); icon_column->add_attribute(sel->icon_renderer->property_pixbuf(), sel->columns->pixbuf); icon_column->set_sort_column(sel->columns->color); icon_column->set_clickable(true); - sel->treeview->append_column("Name", *sel->text_renderer); + sel->treeview->append_column(_("Name"), *sel->text_renderer); Gtk::TreeView::Column* name_column = sel->treeview->get_column(1); sel->text_renderer->property_editable() = true; name_column->add_attribute(sel->text_renderer->property_text(), sel->columns->name); - name_column->set_min_width(200); + name_column->set_min_width(180); name_column->set_clickable(true); name_column->set_resizable(true); @@ -169,7 +173,7 @@ static void sp_gradient_selector_init(SPGradientSelector *sel) count_column->signal_clicked().connect( sigc::mem_fun(*sel, &SPGradientSelector::onTreeCountColClick) ); gvs->tree_select_connection = sel->treeview->get_selection()->signal_changed().connect( sigc::mem_fun(*sel, &SPGradientSelector::onTreeSelection) ); - sel->text_renderer->signal_edited().connect( sigc::mem_fun(*sel, &SPGradientSelector::onTreeEdited) ); + sel->text_renderer->signal_edited().connect( sigc::mem_fun(*sel, &SPGradientSelector::onGradientRename) ); sel->scrolled_window = Gtk::manage(new Gtk::ScrolledWindow()); sel->scrolled_window->add(*sel->treeview); @@ -188,11 +192,11 @@ static void sp_gradient_selector_init(SPGradientSelector *sel) #else GtkWidget *hb = gtk_hbox_new( FALSE, 2 ); #endif - sel->nonsolid.push_back(hb); + //sel->nonsolid.push_back(hb); gtk_box_pack_start( GTK_BOX(sel), hb, FALSE, FALSE, 0 ); sel->add = gtk_button_new (); - gtk_button_set_image((GtkButton*)sel->add , gtk_image_new_from_stock ( GTK_STOCK_ADD, GTK_ICON_SIZE_SMALL_TOOLBAR ) ); + gtk_button_set_image(GTK_BUTTON(sel->add), gtk_image_new_from_stock ( GTK_STOCK_ADD, GTK_ICON_SIZE_SMALL_TOOLBAR ) ); sel->nonsolid.push_back(sel->add); gtk_box_pack_start (GTK_BOX (hb), sel->add, FALSE, FALSE, 0); @@ -203,7 +207,7 @@ static void sp_gradient_selector_init(SPGradientSelector *sel) gtk_widget_set_tooltip_text( sel->add, _("Create a duplicate gradient")); sel->edit = gtk_button_new (); - gtk_button_set_image((GtkButton*)sel->edit , gtk_image_new_from_stock ( GTK_STOCK_EDIT, GTK_ICON_SIZE_SMALL_TOOLBAR ) ); + gtk_button_set_image(GTK_BUTTON(sel->edit), gtk_image_new_from_stock ( GTK_STOCK_EDIT, GTK_ICON_SIZE_SMALL_TOOLBAR ) ); sel->nonsolid.push_back(sel->edit); gtk_box_pack_start (GTK_BOX (hb), sel->edit, FALSE, FALSE, 0); @@ -212,6 +216,16 @@ static void sp_gradient_selector_init(SPGradientSelector *sel) gtk_button_set_relief(GTK_BUTTON(sel->edit), GTK_RELIEF_NONE); gtk_widget_set_tooltip_text( sel->edit, _("Edit gradient")); + sel->del = gtk_button_new (); + gtk_button_set_image(GTK_BUTTON(sel->del), gtk_image_new_from_stock ( GTK_STOCK_REMOVE, GTK_ICON_SIZE_SMALL_TOOLBAR ) ); + + sel->swatch_widgets.push_back(sel->del); + gtk_box_pack_start (GTK_BOX (hb), sel->del, FALSE, FALSE, 0); + g_signal_connect (G_OBJECT (sel->del), "clicked", G_CALLBACK (sp_gradient_selector_delete_vector_clicked), sel); + gtk_widget_set_sensitive (sel->del, FALSE); + gtk_button_set_relief(GTK_BUTTON(sel->del), GTK_RELIEF_NONE); + gtk_widget_set_tooltip_text( sel->del, _("Delete swatch")); + gtk_widget_show_all(hb); @@ -225,6 +239,7 @@ static void sp_gradient_selector_dispose(GObject *object) sel->safelyInit = false; using std::vector; sel->nonsolid.~vector<GtkWidget*>(); + sel->swatch_widgets.~vector<GtkWidget*>(); } if (sel->icon_renderer) { @@ -236,8 +251,8 @@ static void sp_gradient_selector_dispose(GObject *object) sel->text_renderer = NULL; } - if (((GObjectClass *) (parent_class))->dispose) { - (* ((GObjectClass *) (parent_class))->dispose) (object); + if ((G_OBJECT_CLASS(parent_class))->dispose) { + (* (G_OBJECT_CLASS(parent_class))->dispose) (object); } } @@ -248,14 +263,11 @@ void SPGradientSelector::setSpread(SPGradientSpread spread) } -GtkWidget * -sp_gradient_selector_new (void) +GtkWidget *sp_gradient_selector_new() { - SPGradientSelector *sel; - - sel = (SPGradientSelector*)g_object_new (SP_TYPE_GRADIENT_SELECTOR, NULL); + SPGradientSelector *sel = SP_GRADIENT_SELECTOR(g_object_new (SP_TYPE_GRADIENT_SELECTOR, NULL)); - return (GtkWidget *) sel; + return GTK_WIDGET(sel); } void SPGradientSelector::setMode(SelectorMode mode) @@ -267,9 +279,28 @@ void SPGradientSelector::setMode(SelectorMode mode) { gtk_widget_hide(*it); } + for (std::vector<GtkWidget*>::iterator it = swatch_widgets.begin(); it != swatch_widgets.end(); ++it) + { + gtk_widget_show_all(*it); + } + + Gtk::TreeView::Column* icon_column = treeview->get_column(0); + icon_column->set_title(_("Swatch")); SPGradientVectorSelector* vs = SP_GRADIENT_VECTOR_SELECTOR(vectors); vs->setSwatched(); + } else { + for (std::vector<GtkWidget*>::iterator it = nonsolid.begin(); it != nonsolid.end(); ++it) + { + gtk_widget_show_all(*it); + } + for (std::vector<GtkWidget*>::iterator it = swatch_widgets.begin(); it != swatch_widgets.end(); ++it) + { + gtk_widget_hide(*it); + } + Gtk::TreeView::Column* icon_column = treeview->get_column(0); + icon_column->set_title(_("Gradient")); + } } } @@ -289,7 +320,7 @@ SPGradientSpread SPGradientSelector::getSpread() return gradientSpread; } -void SPGradientSelector::onTreeEdited( const Glib::ustring& path_string, const Glib::ustring& new_text) +void SPGradientSelector::onGradientRename( const Glib::ustring& path_string, const Glib::ustring& new_text) { Gtk::TreePath path(path_string); Gtk::TreeModel::iterator iter = store->get_iter(path); @@ -300,10 +331,12 @@ void SPGradientSelector::onTreeEdited( const Glib::ustring& path_string, const G if ( row ) { SPObject* obj = row[columns->data]; if ( obj ) { + row[columns->name] = gr_prepare_label(obj); if (!new_text.empty() && new_text != row[columns->name]) { rename_id(obj, new_text ); + Inkscape::DocumentUndo::done(obj->document, SP_VERB_CONTEXT_GRADIENT, + _("Rename gradient")); } - row[columns->name] = gr_prepare_label(obj); } } } @@ -336,6 +369,14 @@ void SPGradientSelector::onTreeSelection() return; } + if (!treeview->has_focus()) { + /* Workaround for GTK bug on Windows/OS X + * When the treeview initially doesn't have focus and is clicked + * sometimes get_selection()->signal_changed() has the wrong selection + */ + treeview->grab_focus(); + } + const Glib::RefPtr<Gtk::TreeSelection> sel = treeview->get_selection(); if (!sel) { return; @@ -350,7 +391,7 @@ void SPGradientSelector::onTreeSelection() } if (obj) { - sp_gradient_selector_vector_set (NULL, (SPGradient*)obj, this); + sp_gradient_selector_vector_set (NULL, SP_GRADIENT(obj), this); } } @@ -363,7 +404,10 @@ bool SPGradientSelector::_checkForSelected(const Gtk::TreePath &path, const Gtk: { treeview->scroll_to_row(path, 0.5); Glib::RefPtr<Gtk::TreeSelection> select = treeview->get_selection(); + bool wasBlocked = blocked; + blocked = true; select->select(iter); + blocked = wasBlocked; found = true; } @@ -401,6 +445,17 @@ void SPGradientSelector::setVector(SPDocument *doc, SPGradient *vector) gtk_widget_show_all(*it); } } + } else if (mode != MODE_SWATCH) { + + for (std::vector<GtkWidget*>::iterator it = swatch_widgets.begin(); it != swatch_widgets.end(); ++it) + { + gtk_widget_hide(*it); + } + for (std::vector<GtkWidget*>::iterator it = nonsolid.begin(); it != nonsolid.end(); ++it) + { + gtk_widget_show_all(*it); + } + } if (edit) { @@ -409,6 +464,9 @@ void SPGradientSelector::setVector(SPDocument *doc, SPGradient *vector) if (add) { gtk_widget_set_sensitive(add, TRUE); } + if (del) { + gtk_widget_set_sensitive(del, TRUE); + } } else { if (edit) { gtk_widget_set_sensitive(edit, FALSE); @@ -416,6 +474,9 @@ void SPGradientSelector::setVector(SPDocument *doc, SPGradient *vector) if (add) { gtk_widget_set_sensitive(add, (doc != NULL)); } + if (del) { + gtk_widget_set_sensitive(del, FALSE); + } } } @@ -426,8 +487,7 @@ SPGradient *SPGradientSelector::getVector() } -static void -sp_gradient_selector_vector_set (SPGradientVectorSelector *gvs, SPGradient *gr, SPGradientSelector *sel) +static void sp_gradient_selector_vector_set(SPGradientVectorSelector * /*gvs*/, SPGradient *gr, SPGradientSelector *sel) { if (!sel->blocked) { @@ -436,8 +496,30 @@ sp_gradient_selector_vector_set (SPGradientVectorSelector *gvs, SPGradient *gr, sel->setVector((gr) ? gr->document : 0, gr); g_signal_emit (G_OBJECT (sel), signals[CHANGED], 0, gr); sel->blocked = FALSE; + } +} + +static void +sp_gradient_selector_delete_vector_clicked (GtkWidget */*w*/, SPGradientSelector *sel) +{ + const Glib::RefPtr<Gtk::TreeSelection> selection = sel->treeview->get_selection(); + if (!selection) { + return; } + + SPGradient *obj = NULL; + /* Single selection */ + Gtk::TreeModel::iterator iter = selection->get_selected(); + if ( iter ) { + Gtk::TreeModel::Row row = *iter; + obj = row[sel->columns->data]; + } + + if (obj) { + sp_gradient_unset_swatch(SP_ACTIVE_DESKTOP, obj->getId()); + } + } static void @@ -494,7 +576,7 @@ sp_gradient_selector_add_vector_clicked (GtkWidget */*w*/, SPGradientSelector *s Glib::ustring old_id = gr->getId(); - gr = (SPGradient *) doc->getObjectByRepr(repr); + gr = SP_GRADIENT(doc->getObjectByRepr(repr)); // Rename the new gradients id to be similar to the cloned gradients rename_id(gr, old_id); diff --git a/src/widgets/gradient-selector.h b/src/widgets/gradient-selector.h index f7cc3cc14..ea83ff819 100644 --- a/src/widgets/gradient-selector.h +++ b/src/widgets/gradient-selector.h @@ -61,7 +61,7 @@ struct SPGradientSelector { /* Tree */ bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPGradient *vector); void onTreeSelection(); - void onTreeEdited( const Glib::ustring& path_string, const Glib::ustring& new_text); + void onGradientRename( const Glib::ustring& path_string, const Glib::ustring& new_text); void onTreeNameColClick(); void onTreeColorColClick(); void onTreeCountColClick(); @@ -97,6 +97,7 @@ struct SPGradientSelector { /* Editing buttons */ GtkWidget *edit; GtkWidget *add; + GtkWidget *del; GtkWidget *merge; /* Position widget */ @@ -106,6 +107,7 @@ struct SPGradientSelector { bool blocked; std::vector<GtkWidget*> nonsolid; + std::vector<GtkWidget*> swatch_widgets; void setMode(SelectorMode mode); void setUnits(SPGradientUnits units); diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp index 295f211b0..ea125a380 100644 --- a/src/widgets/gradient-toolbar.cpp +++ b/src/widgets/gradient-toolbar.cpp @@ -55,6 +55,7 @@ #include "svg/svg-color.h" #include "desktop-style.h" #include "gradient-context.h" +#include "gradient-toolbar.h" #include "toolbox.h" @@ -122,7 +123,7 @@ void gr_apply_gradient(Inkscape::Selection *selection, GrDrag *drag, SPGradient if (drag && drag->selected) { GrDragger *dragger = static_cast<GrDragger*>(drag->selected->data); for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger - GrDraggable *draggable = (GrDraggable *) i->data; + GrDraggable *draggable = static_cast<GrDraggable*>(i->data); gr_apply_gradient_to_item(draggable->item, gr, initialType, initialMode, draggable->fill_or_stroke); } return; @@ -633,27 +634,7 @@ static void gr_linked_changed(GtkToggleAction *act, gpointer /*data*/) static void gr_reverse(GtkWidget * /*button*/, gpointer data) { SPDesktop *desktop = static_cast<SPDesktop *>(data); - Inkscape::Selection *selection = sp_desktop_selection(desktop); - SPEventContext *ev = sp_desktop_event_context(desktop); - - if (!ev) { - return; - } - - GrDrag *drag = ev->get_drag(); - - // First try selected dragger - if (drag && drag->selected) { - drag->selected_reverse_vector(); - } else { // If no drag or no dragger selected, act on selection (both fill and stroke gradients) - for (GSList const* i = selection->itemList(); i != NULL; i = i->next) { - sp_item_gradient_reverse_vector(SP_ITEM(i->data), Inkscape::FOR_FILL); - sp_item_gradient_reverse_vector(SP_ITEM(i->data), Inkscape::FOR_STROKE); - } - } - // we did an undoable action - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_GRADIENT, - _("Invert gradient")); + sp_gradient_reverse_selected_gradients(desktop); } /* @@ -671,22 +652,8 @@ static void select_drag_by_stop( GtkWidget *data, SPGradient *gradient, SPEventC SPStop *stop = get_selected_stop(data); - - SPStop *stop_iter; - GList *i; - - // Walk thru the draggers and the gradient stops at the same time - for (i = drag->draggers, stop_iter = gradient->getFirstStop(); - i != NULL && stop_iter && SP_IS_STOP(stop_iter); - i = i->next, stop_iter = SP_STOP(stop_iter->getNext())) { - - if (stop == stop_iter) { - GrDragger *d = (GrDragger *) i->data; - drag->setSelected(d, false, true); - blocked = FALSE; - return; - } - } + drag->selectByStop(stop, false, true); + blocked = FALSE; } static void select_stop_by_drag(GtkWidget *combo_box, SPGradient *gradient, SPEventContext *ev, GtkWidget *data) @@ -708,10 +675,10 @@ static void select_stop_by_drag(GtkWidget *combo_box, SPGradient *gradient, SPEv // for all selected draggers for (GList *i = drag->selected; i != NULL; i = i->next) { - GrDragger *dragger = (GrDragger *) i->data; + GrDragger *dragger = static_cast<GrDragger*>(i->data); // for all draggables of dragger for (GSList const* j = dragger->draggables; j != NULL; j = j->next) { - GrDraggable *draggable = (GrDraggable *) j->data; + GrDraggable *draggable = static_cast<GrDraggable*>(j->data); if (draggable->point_type != POINT_RG_FOCUS) { n++; @@ -952,7 +919,7 @@ static void gr_new_fillstroke_changed( EgeSelectOneAction *act, GObject * /*tbl* /* * User selected a gradient from the combobox */ -void gr_gradient_combo_changed(EgeSelectOneAction *act, gpointer data) +static void gr_gradient_combo_changed(EgeSelectOneAction *act, gpointer data) { if (blocked) { return; @@ -981,7 +948,7 @@ void gr_gradient_combo_changed(EgeSelectOneAction *act, gpointer data) } -void gr_spread_change(EgeSelectOneAction *act, GtkWidget *widget) +static void gr_spread_change(EgeSelectOneAction *act, GtkWidget *widget) { if (blocked) { return; @@ -1142,7 +1109,7 @@ void sp_gradient_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, _("No gradient"), 1, NULL, 2, NULL, -1); - EgeSelectOneAction* act1 = ege_select_one_action_new( "GradientSelectGradientAction", _("Select"), ("Choose a gradient"), NULL, GTK_TREE_MODEL(store) ); + EgeSelectOneAction* act1 = ege_select_one_action_new( "GradientSelectGradientAction", _("Select"), (_("Choose a gradient")), NULL, GTK_TREE_MODEL(store) ); g_object_set( act1, "short_label", _("Select:"), NULL ); ege_select_one_action_set_appearance( act1, "compact" ); gtk_action_set_sensitive( GTK_ACTION(act1), FALSE ); @@ -1158,13 +1125,13 @@ void sp_gradient_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GtkTreeIter iter; gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, _("none"), 1, SP_GRADIENT_SPREAD_PAD, -1 ); + gtk_list_store_set( model, &iter, 0, _("None"), 1, SP_GRADIENT_SPREAD_PAD, -1 ); gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, _("reflected"), 1, SP_GRADIENT_SPREAD_REFLECT, -1 ); + gtk_list_store_set( model, &iter, 0, _("Reflected"), 1, SP_GRADIENT_SPREAD_REFLECT, -1 ); gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, _("direct"), 1, SP_GRADIENT_SPREAD_REPEAT, -1 ); + gtk_list_store_set( model, &iter, 0, _("Direct"), 1, SP_GRADIENT_SPREAD_REPEAT, -1 ); EgeSelectOneAction* act1 = ege_select_one_action_new( "GradientSelectRepeatAction", _("Repeat"), (// TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute @@ -1190,7 +1157,7 @@ void sp_gradient_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, gtk_list_store_set(store, &iter, 0, _("No gradient"), 1, NULL, 2, NULL, -1); EgeSelectOneAction* act1 = ege_select_one_action_new( "GradientEditStopsAction", _("Stops"), _("Select a stop for the current gradient"), NULL, GTK_TREE_MODEL(store) ); - g_object_set( act1, "short_label", _("Edit:"), NULL ); + g_object_set( act1, "short_label", _("Stops:"), NULL ); ege_select_one_action_set_appearance( act1, "compact" ); gtk_action_set_sensitive( GTK_ACTION(act1), FALSE ); g_signal_connect( G_OBJECT(act1), "changed", G_CALLBACK(gr_stop_combo_changed), holder ); @@ -1265,7 +1232,7 @@ void sp_gradient_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, _("Link gradients"), _("Link gradients to change all related gradients"), INKSCAPE_ICON("object-unlocked"), - secondarySize ); + Inkscape::ICON_SIZE_DECORATION ); g_object_set( itact, "short_label", "Lock", NULL ); g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(gr_linked_changed), desktop) ; gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); diff --git a/src/widgets/gradient-toolbar.h b/src/widgets/gradient-toolbar.h index 980a41a83..74cfb2886 100644 --- a/src/widgets/gradient-toolbar.h +++ b/src/widgets/gradient-toolbar.h @@ -13,7 +13,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_gradient_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index db8c76b9b..e15f81e0f 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -22,10 +22,9 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif -#ifdef HAVE_STRING_H -#endif -#include "ui/widget/color-preview.h" + #include "gradient-vector.h" +#include "ui/widget/color-preview.h" #include "verbs.h" #include <gtk/gtk.h> #include "macros.h" @@ -377,7 +376,7 @@ unsigned long sp_gradient_to_hhssll(SPGradient *gr) return ((int)(hsl[0]*100 * 10000)) + ((int)(hsl[1]*100 * 100)) + ((int)(hsl[2]*100 * 1)); } -GSList *get_all_doc_items(GSList *list, SPObject *from, bool onlyvisible, bool onlysensitive, bool ingroups, GSList const *exclude) +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)) { @@ -430,6 +429,8 @@ void gr_get_usage_counts(SPDocument *doc, std::map<SPGradient *, gint> *mapUsage for (GSList *i = all_list; i != NULL; i = i->next) { SPItem *item = SP_ITEM(i->data); + if (!item->getId()) + continue; SPGradient *gr = NULL; gr = gr_item_get_gradient(item, true); // fill if (gr) { @@ -607,7 +608,7 @@ static void update_stop_list( GtkWidget *vb, SPGradient *gradient, SPStop *new_s if (!combo_box) { return; } - GtkListStore *store = (GtkListStore *)gtk_combo_box_get_model (GTK_COMBO_BOX(combo_box)); + GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo_box))); if (!store) { return; } @@ -718,7 +719,7 @@ static SPStop *get_selected_stop( GtkWidget *vb) if (combo_box) { GtkTreeIter iter; if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX(combo_box), &iter)) { - GtkListStore *store = (GtkListStore *)gtk_combo_box_get_model (GTK_COMBO_BOX(combo_box)); + GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo_box))); gtk_tree_model_get (GTK_TREE_MODEL(store), &iter, 2, &stop, -1); } } @@ -929,7 +930,7 @@ static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *s /* Adjustment */ GtkAdjustment *Offset_adj = NULL; - Offset_adj= (GtkAdjustment *) gtk_adjustment_new(0.0, 0.0, 1.0, 0.01, 0.01, 0.0); + Offset_adj= GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 1.0, 0.01, 0.01, 0.0)); g_object_set_data(G_OBJECT(vb), "offset", Offset_adj); SPStop *stop = get_selected_stop(vb); @@ -1195,10 +1196,10 @@ static void sp_gradient_vector_widget_destroy(GtkWidget *object, gpointer /*data static void sp_gradient_vector_widget_destroy(GtkObject *object, gpointer /*data*/) #endif { - SPObject *gradient = reinterpret_cast<SPObject*>(g_object_get_data(G_OBJECT(object), "gradient")); + SPObject *gradient = SP_OBJECT(g_object_get_data(G_OBJECT(object), "gradient")); - sigc::connection *release_connection = (sigc::connection *)g_object_get_data(G_OBJECT(object), "gradient_release_connection"); - sigc::connection *modified_connection = (sigc::connection *)g_object_get_data(G_OBJECT(object), "gradient_modified_connection"); + sigc::connection *release_connection = static_cast<sigc::connection *>(g_object_get_data(G_OBJECT(object), "gradient_release_connection")); + sigc::connection *modified_connection = static_cast<sigc::connection *>(g_object_get_data(G_OBJECT(object), "gradient_modified_connection")); if (gradient) { g_assert( release_connection != NULL ); @@ -1314,7 +1315,7 @@ static void sp_gradient_vector_color_changed(SPColorSelector *csel, GObject *obj if (combo_box) { GtkTreeIter iter; if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX(combo_box), &iter)) { - GtkListStore *store = (GtkListStore *)gtk_combo_box_get_model (GTK_COMBO_BOX(combo_box)); + GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo_box))); Inkscape::UI::Widget::ColorPreview *cp = Gtk::manage(new Inkscape::UI::Widget::ColorPreview(sp_stop_get_rgba32(stop))); GdkPixbuf *pb = cp->toPixbuf(64, 16); diff --git a/src/widgets/gradient-vector.h b/src/widgets/gradient-vector.h index 1ed6c6c46..463d77912 100644 --- a/src/widgets/gradient-vector.h +++ b/src/widgets/gradient-vector.h @@ -15,7 +15,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <glib.h> #include <gtkmm/liststore.h> #include <stddef.h> @@ -33,7 +32,7 @@ class SPDocument; class SPObject; class SPGradient; -class SPStop; +struct SPStop; struct SPGradientVectorSelector { GtkVBox vbox; diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index c02f4bceb..7580d9602 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -24,6 +24,7 @@ #include <gtkmm/image.h> #include <gdkmm/pixbuf.h> #include <glibmm/fileutils.h> +#include <glibmm/miscutils.h> #include <2geom/transforms.h> #include "path-prefix.h" @@ -40,19 +41,7 @@ #include "icon.h" -// Bring in work-around for Glib versions missing GStatBuf -#if !GLIB_CHECK_VERSION(2,25,0) -#if defined (_MSC_VER) && !defined(_WIN64) -typedef struct _stat32 GStatBuf; -#else //defined (_MSC_VER) && !defined(_WIN64) -typedef struct stat GStatBuf; -#endif //defined (_MSC_VER) && !defined(_WIN64) -#endif //!GLIB_CHECK_VERSION(2,25,0) - struct IconImpl { - static void classInit(SPIconClass *klass); - static void init(SPIcon *icon); - static GtkWidget *newFull( Inkscape::IconSize lsize, gchar const *name ); static void dispose(GObject *object); @@ -113,12 +102,10 @@ struct IconImpl { private: static const std::string magicNumber; - static GtkWidgetClass *parent_class; static std::map<Glib::ustring, Glib::ustring> legacyNames; }; const std::string IconImpl::magicNumber = "1.0"; -GtkWidgetClass *IconImpl::parent_class = 0; std::map<Glib::ustring, Glib::ustring> IconImpl::legacyNames; @@ -150,36 +137,13 @@ public: static std::map<Glib::ustring, std::vector<IconCacheItem> > iconSetCache; static std::set<Glib::ustring> internalNames; -GType SPIcon::getType() -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPIconClass), - NULL, - NULL, - reinterpret_cast<GClassInitFunc>(IconImpl::classInit), - NULL, - NULL, - sizeof(SPIcon), - 0, - reinterpret_cast<GInstanceInitFunc>(IconImpl::init), - NULL - }; - type = g_type_register_static(GTK_TYPE_WIDGET, "SPIcon", &info, (GTypeFlags)0); - } - return type; -} +G_DEFINE_TYPE(SPIcon, sp_icon, GTK_TYPE_WIDGET); -void IconImpl::classInit(SPIconClass *klass) +static void +sp_icon_class_init(SPIconClass *klass) { - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GObjectClass *) klass; - widget_class = (GtkWidgetClass *) klass; - - parent_class = (GtkWidgetClass*)g_type_class_peek_parent(klass); + GObjectClass *object_class = G_OBJECT_CLASS(klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); object_class->dispose = IconImpl::dispose; @@ -196,7 +160,8 @@ void IconImpl::classInit(SPIconClass *klass) widget_class->style_set = IconImpl::styleSet; } -void IconImpl::init(SPIcon *icon) +static void +sp_icon_init(SPIcon *icon) { gtk_widget_set_has_window (GTK_WIDGET (icon), FALSE); icon->lsize = Inkscape::ICON_SIZE_BUTTON; @@ -214,7 +179,7 @@ void IconImpl::dispose(GObject *object) icon->name = 0; } - ((GObjectClass *) (parent_class))->dispose(object); + (G_OBJECT_CLASS(sp_icon_parent_class))->dispose(object); } void IconImpl::reset( SPIcon *icon ) @@ -321,7 +286,7 @@ gboolean IconImpl::draw(GtkWidget *widget, cairo_t* cr) } #if !GTK_CHECK_VERSION(3,0,0) -gboolean IconImpl::expose(GtkWidget *widget, GdkEventExpose *event) +gboolean IconImpl::expose(GtkWidget *widget, GdkEventExpose * /*event*/) { gboolean result = TRUE; @@ -387,8 +352,8 @@ GdkPixbuf* IconImpl::renderup( gchar const* name, Inkscape::IconSize lsize, unsi void IconImpl::screenChanged( GtkWidget *widget, GdkScreen *previous_screen ) { - if ( GTK_WIDGET_CLASS( parent_class )->screen_changed ) { - GTK_WIDGET_CLASS( parent_class )->screen_changed( widget, previous_screen ); + if ( GTK_WIDGET_CLASS( sp_icon_parent_class )->screen_changed ) { + GTK_WIDGET_CLASS( sp_icon_parent_class )->screen_changed( widget, previous_screen ); } SPIcon *icon = SP_ICON(widget); themeChanged(icon); @@ -396,8 +361,8 @@ void IconImpl::screenChanged( GtkWidget *widget, GdkScreen *previous_screen ) void IconImpl::styleSet( GtkWidget *widget, GtkStyle *previous_style ) { - if ( GTK_WIDGET_CLASS( parent_class )->style_set ) { - GTK_WIDGET_CLASS( parent_class )->style_set( widget, previous_style ); + if ( GTK_WIDGET_CLASS( sp_icon_parent_class )->style_set ) { + GTK_WIDGET_CLASS( sp_icon_parent_class )->style_set( widget, previous_style ); } SPIcon *icon = SP_ICON(widget); themeChanged(icon); @@ -874,14 +839,14 @@ GtkWidget *IconImpl::newFull( Inkscape::IconSize lsize, gchar const *name ) if ( dump ) { g_message( "skipped gtk '%s' %d (not GTK_IMAGE_STOCK)", name, lsize ); } - //g_object_unref( (GObject *)img ); + //g_object_unref(G_OBJECT(img)); img = 0; } } if ( !widget ) { //g_message("Creating an SPIcon instance for %s:%d", name, (int)lsize); - SPIcon *icon = (SPIcon *)g_object_new(SP_TYPE_ICON, NULL); + SPIcon *icon = SP_ICON(g_object_new(SP_TYPE_ICON, NULL)); icon->lsize = lsize; icon->name = g_strdup(name); icon->psize = getPhysSize(lsize); @@ -1031,7 +996,7 @@ int IconImpl::getPhysSize(int size) "inkscape-decoration" }; - GtkWidget *icon = (GtkWidget *)g_object_new(SP_TYPE_ICON, NULL); + GtkWidget *icon = GTK_WIDGET(g_object_new(SP_TYPE_ICON, NULL)); for (unsigned i = 0; i < G_N_ELEMENTS(gtkSizes); ++i) { guint const val_ix = (gtkSizes[i] <= GTK_ICON_SIZE_DIALOG) ? (guint)gtkSizes[i] : (guint)Inkscape::ICON_SIZE_DECORATION; @@ -1084,7 +1049,7 @@ int IconImpl::getPhysSize(int size) GdkPixbuf *IconImpl::loadPixmap(gchar const *name, unsigned /*lsize*/, unsigned psize) { - gchar *path = (gchar *) g_strdup_printf("%s/%s.png", INKSCAPE_PIXMAPDIR, name); + gchar *path = g_strdup_printf("%s/%s.png", INKSCAPE_PIXMAPDIR, name); // TODO: bulia, please look over gsize bytesRead = 0; gsize bytesWritten = 0; @@ -1098,7 +1063,7 @@ GdkPixbuf *IconImpl::loadPixmap(gchar const *name, unsigned /*lsize*/, unsigned g_free(localFilename); g_free(path); if (!pb) { - path = (gchar *) g_strdup_printf("%s/%s.xpm", INKSCAPE_PIXMAPDIR, name); + path = g_strdup_printf("%s/%s.xpm", INKSCAPE_PIXMAPDIR, name); // TODO: bulia, please look over gsize bytesRead = 0; gsize bytesWritten = 0; diff --git a/src/widgets/icon.h b/src/widgets/icon.h index 3f6aa2455..6bce2e330 100644 --- a/src/widgets/icon.h +++ b/src/widgets/icon.h @@ -17,7 +17,7 @@ #include <gtkmm/widget.h> #include "icon-size.h" -#define SP_TYPE_ICON SPIcon::getType() +#define SP_TYPE_ICON sp_icon_get_type() #define SP_ICON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_ICON, SPIcon)) #define SP_IS_ICON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_ICON)) @@ -29,6 +29,8 @@ struct SPIconClass { GtkWidgetClass parent_class; }; +GType sp_icon_get_type() G_GNUC_CONST; + struct SPIcon { GtkWidget widget; @@ -38,8 +40,6 @@ struct SPIcon { GdkPixbuf *pb; - static GType getType(void); - friend class SPIconImpl; }; diff --git a/src/widgets/lpe-toolbar.cpp b/src/widgets/lpe-toolbar.cpp index 673b1588b..3126175b3 100644 --- a/src/widgets/lpe-toolbar.cpp +++ b/src/widgets/lpe-toolbar.cpp @@ -83,7 +83,7 @@ static void sp_lpetool_mode_changed(EgeSelectOneAction *act, GObject *tbl) { using namespace Inkscape::LivePathEffect; - SPDesktop *desktop = (SPDesktop *) g_object_get_data(tbl, "desktop"); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(tbl, "desktop")); SPEventContext *ec = desktop->event_context; if (!SP_IS_LPETOOL_CONTEXT(ec)) { return; @@ -199,7 +199,7 @@ static void lpetool_unit_changed(GtkAction* /*act*/, GObject* tbl) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setInt("/tools/lpetool/unitid", unit->unit_id); - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); if (SP_IS_LPETOOL_CONTEXT(desktop->event_context)) { SPLPEToolContext *lc = SP_LPETOOL_CONTEXT(desktop->event_context); lpetool_delete_measuring_items(lc); @@ -399,7 +399,7 @@ void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GO { GtkAction* act = tracker->createAction( "LPEToolUnitsAction", _("Units"), ("") ); gtk_action_group_add_action( mainActions, act ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(lpetool_unit_changed), (GObject*)holder ); + g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(lpetool_unit_changed), holder ); g_object_set_data(holder, "lpetool_units_action", act); gtk_action_set_sensitive(act, prefs->getBool("/tools/lpetool/show_measuring_info", true)); } @@ -421,12 +421,12 @@ void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GO sigc::connection *c_selection_modified = new sigc::connection (sp_desktop_selection (desktop)->connectModified - (sigc::bind (sigc::ptr_fun (sp_lpetool_toolbox_sel_modified), (GObject*)holder))); + (sigc::bind (sigc::ptr_fun (sp_lpetool_toolbox_sel_modified), holder))); pool->add_connection ("selection-modified", c_selection_modified); sigc::connection *c_selection_changed = new sigc::connection (sp_desktop_selection (desktop)->connectChanged - (sigc::bind (sigc::ptr_fun(sp_lpetool_toolbox_sel_changed), (GObject*)holder))); + (sigc::bind (sigc::ptr_fun(sp_lpetool_toolbox_sel_changed), holder))); pool->add_connection ("selection-changed", c_selection_changed); } diff --git a/src/widgets/lpe-toolbar.h b/src/widgets/lpe-toolbar.h index 837ef4c1e..1796f8027 100644 --- a/src/widgets/lpe-toolbar.h +++ b/src/widgets/lpe-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 2153aba51..21df4c6d9 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -28,9 +28,8 @@ # include "config.h" #endif -#include <glibmm/i18n.h> - #include "ui/widget/spinbutton.h" +#include <glibmm/i18n.h> #include "toolbox.h" #include "measure-toolbar.h" @@ -72,7 +71,7 @@ using Inkscape::UI::PrefPusher; static void sp_measure_fontsize_value_changed(GtkAdjustment *adj, GObject *tbl) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -122,7 +121,7 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G // units menu { GtkAction* act = tracker->createAction( "MeasureUnitsAction", _("Units:"), _("The units to be used for the measurements") ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(measure_unit_changed), (GObject*)holder ); + g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(measure_unit_changed), holder ); gtk_action_group_add_action( mainActions, act ); } } // end of sp_measure_toolbox_prep() diff --git a/src/widgets/measure-toolbar.h b/src/widgets/measure-toolbar.h index 7ec6cd6c3..4b90ccb9f 100644 --- a/src/widgets/measure-toolbar.h +++ b/src/widgets/measure-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_measure_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/mesh-toolbar.h b/src/widgets/mesh-toolbar.h index 277525804..f84cff59b 100644 --- a/src/widgets/mesh-toolbar.h +++ b/src/widgets/mesh-toolbar.h @@ -15,7 +15,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_mesh_toolbox_prep( SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/node-toolbar.cpp b/src/widgets/node-toolbar.cpp index 7dca63ba2..849de874d 100644 --- a/src/widgets/node-toolbar.cpp +++ b/src/widgets/node-toolbar.cpp @@ -28,9 +28,8 @@ # include "config.h" #endif -#include <glibmm/i18n.h> - #include "ui/widget/spinbutton.h" +#include <glibmm/i18n.h> #include "toolbox.h" #include "node-toolbar.h" @@ -266,7 +265,7 @@ static void sp_node_toolbox_coord_changed(gpointer /*shape_editor*/, GObject *tb static void sp_node_path_value_changed(GtkAdjustment *adj, GObject *tbl, Geom::Dim2 d) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" )); @@ -632,17 +631,17 @@ void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje sigc::connection *c_selection_changed = new sigc::connection (sp_desktop_selection (desktop)->connectChanged - (sigc::bind (sigc::ptr_fun (sp_node_toolbox_sel_changed), (GObject*)holder))); + (sigc::bind (sigc::ptr_fun (sp_node_toolbox_sel_changed), holder))); pool->add_connection ("selection-changed", c_selection_changed); sigc::connection *c_selection_modified = new sigc::connection (sp_desktop_selection (desktop)->connectModified - (sigc::bind (sigc::ptr_fun (sp_node_toolbox_sel_modified), (GObject*)holder))); + (sigc::bind (sigc::ptr_fun (sp_node_toolbox_sel_modified), holder))); pool->add_connection ("selection-modified", c_selection_modified); sigc::connection *c_subselection_changed = new sigc::connection (desktop->connectToolSubselectionChanged - (sigc::bind (sigc::ptr_fun (sp_node_toolbox_coord_changed), (GObject*)holder))); + (sigc::bind (sigc::ptr_fun (sp_node_toolbox_coord_changed), holder))); pool->add_connection ("tool-subselection-changed", c_subselection_changed); Inkscape::ConnectionPool::connect_destroy (G_OBJECT (holder), pool); diff --git a/src/widgets/node-toolbar.h b/src/widgets/node-toolbar.h index ac57a0f80..dcccf1712 100644 --- a/src/widgets/node-toolbar.h +++ b/src/widgets/node-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index 6450abf52..b0738b6a6 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -157,9 +157,9 @@ GType sp_paint_selector_get_type(void) static void sp_paint_selector_class_init(SPPaintSelectorClass *klass) { - GObjectClass *object_class = (GObjectClass *) klass; + GObjectClass *object_class = G_OBJECT_CLASS(klass); - parent_class = (GtkVBoxClass*)g_type_class_peek_parent(klass); + parent_class = GTK_VBOX_CLASS(g_type_class_peek_parent(klass)); psel_signals[MODE_CHANGED] = g_signal_new("mode_changed", G_TYPE_FROM_CLASS(object_class), @@ -311,8 +311,8 @@ static void sp_paint_selector_dispose(GObject *object) // clean up our long-living pattern menu g_object_set_data(G_OBJECT(psel),"patternmenu",NULL); - if (((GObjectClass *) parent_class)->dispose) - (* ((GObjectClass *) parent_class)->dispose)(object); + if ((G_OBJECT_CLASS(parent_class))->dispose) + (* (G_OBJECT_CLASS(parent_class))->dispose)(object); } static GtkWidget *sp_paint_selector_style_button_add(SPPaintSelector *psel, @@ -359,7 +359,7 @@ sp_paint_selector_fillrule_toggled(GtkToggleButton *tb, SPPaintSelector *psel) } } -void +static void sp_paint_selector_show_fillrule(SPPaintSelector *psel, bool is_fill) { if (psel->fillrulebox) { @@ -655,7 +655,7 @@ static void sp_paint_selector_set_mode_color(SPPaintSelector *psel, SPPaintSelec if ((psel->mode == SPPaintSelector::MODE_COLOR_RGB) || (psel->mode == SPPaintSelector::MODE_COLOR_CMYK)) { /* Already have color selector */ - csel = (GtkWidget*)g_object_get_data(G_OBJECT(psel->selector), "color-selector"); + csel = GTK_WIDGET(g_object_get_data(G_OBJECT(psel->selector), "color-selector")); } else { sp_paint_selector_clear_frame(psel); @@ -732,7 +732,7 @@ static void sp_paint_selector_set_mode_gradient(SPPaintSelector *psel, SPPaintSe if ((psel->mode == SPPaintSelector::MODE_GRADIENT_LINEAR) || (psel->mode == SPPaintSelector::MODE_GRADIENT_RADIAL)) { /* Already have gradient selector */ - gsel = (GtkWidget*)g_object_get_data(G_OBJECT(psel->selector), "gradient-selector"); + gsel = GTK_WIDGET(g_object_get_data(G_OBJECT(psel->selector), "gradient-selector")); } else { sp_paint_selector_clear_frame(psel); /* Create new gradient selector */ @@ -791,7 +791,7 @@ static void sp_psel_pattern_change(GtkWidget * /*widget*/, SPPaintSelector *psel * Returns a list of patterns in the defs of the given source document as a GSList object * Returns NULL if there are no patterns in the document. */ -GSList * +static GSList * ink_pattern_list_get (SPDocument *source) { if (source == NULL) @@ -799,7 +799,7 @@ ink_pattern_list_get (SPDocument *source) GSList *pl = NULL; GSList const *patterns = source->getResourceList("pattern"); - for (GSList *l = (GSList *) patterns; l != NULL; l = l->next) { + for (GSList *l = const_cast<GSList *>(patterns); l != NULL; l = l->next) { if (SP_PATTERN(l->data) == pattern_getroot(SP_PATTERN(l->data))) { // only if this is a root pattern pl = g_slist_prepend(pl, l->data); } @@ -995,7 +995,7 @@ static void sp_paint_selector_set_mode_pattern(SPPaintSelector *psel, SPPaintSel if (psel->mode == SPPaintSelector::MODE_PATTERN) { /* Already have pattern menu */ - tbl = (GtkWidget*)g_object_get_data(G_OBJECT(psel->selector), "pattern-selector"); + tbl = GTK_WIDGET(g_object_get_data(G_OBJECT(psel->selector), "pattern-selector")); } else { sp_paint_selector_clear_frame(psel); @@ -1081,7 +1081,7 @@ SPPattern *SPPaintSelector::getPattern() SPPattern *pat = 0; g_return_val_if_fail((mode == MODE_PATTERN) , NULL); - GtkWidget *combo = (GtkWidget *) g_object_get_data(G_OBJECT(this), "patternmenu"); + GtkWidget *combo = GTK_WIDGET(g_object_get_data(G_OBJECT(this), "patternmenu")); /* no pattern menu if we were just selected */ if ( combo == NULL ) { diff --git a/src/widgets/paint-selector.h b/src/widgets/paint-selector.h index d6ad3f50c..a66758434 100644 --- a/src/widgets/paint-selector.h +++ b/src/widgets/paint-selector.h @@ -22,8 +22,8 @@ class SPGradient; class SPDesktop; -class SPPattern; -class SPStyle; +struct SPPattern; +struct SPStyle; #define SP_TYPE_PAINT_SELECTOR (sp_paint_selector_get_type ()) #define SP_PAINT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_PAINT_SELECTOR, SPPaintSelector)) diff --git a/src/widgets/paintbucket-toolbar.cpp b/src/widgets/paintbucket-toolbar.cpp index a99350a44..73815b86d 100644 --- a/src/widgets/paintbucket-toolbar.cpp +++ b/src/widgets/paintbucket-toolbar.cpp @@ -28,10 +28,8 @@ # include "config.h" #endif - -#include <glibmm/i18n.h> - #include "ui/widget/spinbutton.h" +#include <glibmm/i18n.h> #include "toolbox.h" #include "paintbucket-toolbar.h" diff --git a/src/widgets/paintbucket-toolbar.h b/src/widgets/paintbucket-toolbar.h index f49861e1f..fe25c7fe2 100644 --- a/src/widgets/paintbucket-toolbar.h +++ b/src/widgets/paintbucket-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index 73ab4883c..e0cf67bd0 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -28,9 +28,8 @@ # include "config.h" #endif -#include <glibmm/i18n.h> - #include "ui/widget/spinbutton.h" +#include <glibmm/i18n.h> #include "toolbox.h" #include "pencil-toolbar.h" @@ -91,7 +90,7 @@ using Inkscape::UI::PrefPusher; /* This is used in generic functions below to share large portions of code between pen and pencil tool */ static Glib::ustring const freehand_tool_name(GObject *dataKludge) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data(dataKludge, "desktop"); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(dataKludge, "desktop")); return ( tools_isactive(desktop, TOOLS_FREEHAND_PEN) ? "/tools/freehand/pen" : "/tools/freehand/pencil" ); @@ -104,7 +103,7 @@ static void freehand_mode_changed(EgeSelectOneAction* act, GObject* tbl) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setInt(freehand_tool_name(tbl) + "/freehand-mode", mode); - SPDesktop *desktop = (SPDesktop *) g_object_get_data(tbl, "desktop"); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(tbl, "desktop")); // in pen tool we have more options than in pencil tool; if one of them was chosen, we do any // preparatory work here @@ -242,7 +241,7 @@ static void sp_pencil_tb_defaults(GtkWidget * /*widget*/, GObject *obj) // fixme: make settable gdouble tolerance = 4; - adj = (GtkAdjustment*)g_object_get_data(obj, "tolerance"); + adj = GTK_ADJUSTMENT(g_object_get_data(obj, "tolerance")); gtk_adjustment_set_value(adj, tolerance); gtk_adjustment_value_changed(adj); @@ -282,7 +281,7 @@ public: } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - GtkAdjustment * adj = (GtkAdjustment*)g_object_get_data(tbl, "tolerance"); + GtkAdjustment * adj = GTK_ADJUSTMENT(g_object_get_data(tbl, "tolerance")); double v = val.getDouble(adj->value); gtk_adjustment_set_value(adj, v); diff --git a/src/widgets/pencil-toolbar.h b/src/widgets/pencil-toolbar.h index 89269d668..14f1e8930 100644 --- a/src/widgets/pencil-toolbar.h +++ b/src/widgets/pencil-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); void sp_pen_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/rect-toolbar.cpp b/src/widgets/rect-toolbar.cpp index 8e74ff113..8c1a735c5 100644 --- a/src/widgets/rect-toolbar.cpp +++ b/src/widgets/rect-toolbar.cpp @@ -28,9 +28,8 @@ # include "config.h" #endif -#include <glibmm/i18n.h> - #include "ui/widget/spinbutton.h" +#include <glibmm/i18n.h> #include "toolbox.h" #include "rect-toolbar.h" @@ -89,7 +88,7 @@ static void sp_rtb_sensitivize( GObject *tbl ) static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name, void (*setter)(SPRect *, gdouble)) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" )); SPUnit const *unit = tracker->getActiveUnit(); @@ -395,7 +394,7 @@ void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje sp_rtb_sensitivize( holder ); sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), (GObject *)holder)) + sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), holder)) ); g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); diff --git a/src/widgets/rect-toolbar.h b/src/widgets/rect-toolbar.h index 2f22d7e27..e123c095b 100644 --- a/src/widgets/rect-toolbar.h +++ b/src/widgets/rect-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index 72c839b19..c1f9be2a5 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -1,5 +1,18 @@ /* - * Customized ruler class for inkscape + * Customized ruler class for inkscape. Note that this is a fork of + * the GimpRuler widget from GIMP: libgimpwidgets/gimpruler.c. + * The GIMP code is released under the GPL 3. The GIMP code itself + * is a fork of the now-obsolete GtkRuler widget from GTK+ 2. + * + * Major differences between implementations in Inkscape and GIMP are + * as follows: + * - We use a 1,2,4,8... scale for inches and 1,2,5,10... for everything + * else. GIMP uses 1,2,5,10... for everything. + * + * - 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) * * Authors: * Lauris Kaplinski <lauris@kaplinski.com> @@ -7,6 +20,7 @@ * bulia byak <buliabyak@users.sf.net> * Diederik van Lierop <mail@diedenrezi.nl> * Jon A. Cruz <jon@joncruz.org> + * Alex Valavanis <valavanisalex@gmail.com> * * Copyright (C) 1999-2011 authors * @@ -18,143 +32,178 @@ #include <cstdio> #include "widget-sizes.h" -#include "desktop-widget.h" #include "ruler.h" #include "unit-constants.h" #include "round.h" #include <glibmm/i18n.h> -#define GTK_PARAM_READWRITE G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB - -#define MINIMUM_INCR 5 -#define MAXIMUM_SUBDIVIDE 5 -#define MAXIMUM_SCALES 10 - #define ROUND(x) ((int) ((x) + 0.5)) -struct _SPRulerPrivate -{ - GtkOrientation orientation; - SPRulerMetric *metric; +#define GTK_PARAM_READWRITE G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB + +#define DEFAULT_RULER_FONT_SCALE PANGO_SCALE_X_SMALL +#define MINIMUM_INCR 5 -#if GTK_CHECK_VERSION(3,0,0) - cairo_surface_t *backing_store; -#else - GdkPixmap *backing_store; -#endif - - gint slider_size; - gint xsrc; - gint ysrc; - - gdouble lower; /* The upper limit of the ruler (in points) */ - gdouble upper; /* The lower limit of the ruler */ - gdouble position; /* The position of the mark on the ruler */ - gdouble max_size; /* The maximum size of the ruler */ -}; enum { PROP_0, PROP_ORIENTATION, + PROP_UNIT, PROP_LOWER, PROP_UPPER, PROP_POSITION, - PROP_MAX_SIZE, - PROP_METRIC + PROP_MAX_SIZE }; -static void sp_ruler_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void sp_ruler_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void sp_ruler_realize (GtkWidget *widget); -static void sp_ruler_unrealize (GtkWidget *widget); -static void sp_ruler_size_request (GtkWidget *widget, - GtkRequisition *requisition); -#if GTK_CHECK_VERSION(3,0,0) -static void sp_ruler_get_preferred_width (GtkWidget *widget, - gint *minimal_width, - gint *natural_width); +/* All distances below are in 1/72nd's of an inch. (According to + * Adobe, that's a point, but points are really 1/72.27 in.) + */ +typedef struct +{ + GtkOrientation orientation; + SPMetric unit; + gdouble lower; + gdouble upper; + gdouble position; + gdouble max_size; + + GdkWindow *input_window; + cairo_surface_t *backing_store; + PangoLayout *layout; + gdouble font_scale; + + gint xsrc; + gint ysrc; -static void sp_ruler_get_preferred_height (GtkWidget *widget, - gint *minimal_height, - gint *natural_height); -#endif + GList *track_widgets; +} SPRulerPrivate; + +#define SP_RULER_GET_PRIVATE(ruler) \ + G_TYPE_INSTANCE_GET_PRIVATE (ruler, SP_TYPE_RULER, SPRulerPrivate) + + +struct SPRulerMetric +{ + gdouble ruler_scale[16]; + gint subdivide[5]; +}; + +// Ruler metric for general use. +static SPRulerMetric const ruler_metric_general = { + { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 25000, 50000, 100000 }, + { 1, 5, 10, 50, 100 } +}; + +// Ruler metric for inch scales. +static SPRulerMetric const ruler_metric_inches = { + { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 }, + { 1, 2, 4, 8, 16 } +}; + +static void sp_ruler_dispose (GObject *object); +static void sp_ruler_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void sp_ruler_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void sp_ruler_realize (GtkWidget *widget); +static void sp_ruler_unrealize (GtkWidget *widget); +static void sp_ruler_map (GtkWidget *widget); +static void sp_ruler_unmap (GtkWidget *widget); +static void sp_ruler_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); -static void sp_ruler_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gboolean sp_ruler_motion_notify (GtkWidget *widget, - GdkEventMotion *event); #if GTK_CHECK_VERSION(3,0,0) -static gboolean sp_ruler_draw (GtkWidget *widget, - cairo_t *cr); +static void sp_ruler_get_preferred_width (GtkWidget *widget, + gint *minimum_width, + gint *natural_width); + +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 gboolean sp_ruler_expose (GtkWidget *widget, - GdkEventExpose *event); +static void sp_ruler_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static void sp_ruler_style_set (GtkWidget *widget, + GtkStyle *prev_style); #endif -static void sp_ruler_make_pixmap (SPRuler *ruler); -static void sp_ruler_draw_ticks (SPRuler *ruler); -static void sp_ruler_real_draw_ticks (SPRuler *ruler, - cairo_t *cr); -static void sp_ruler_real_draw_pos (SPRuler *ruler, - cairo_t *cr); - -#define SP_RULER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SP_TYPE_RULER, SPRulerPrivate)) - -// Note: const casts are due to SPRuler being const-broken and not scheduled for any more fixes. -/// Ruler metrics. -static SPRulerMetric const sp_ruler_metrics[] = { - // NOTE: the order of records in this struct must correspond to the SPMetric enum. - {const_cast<gchar*>("NONE"), const_cast<gchar*>(""), 1, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }}, - {const_cast<gchar*>("millimeters"), const_cast<gchar*>("mm"), PX_PER_MM, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }}, - {const_cast<gchar*>("centimeters"), const_cast<gchar*>("cm"), PX_PER_CM, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }}, - {const_cast<gchar*>("inches"), const_cast<gchar*>("in"), PX_PER_IN, { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 }, { 1, 2, 4, 8, 16 }}, - {const_cast<gchar*>("feet"), const_cast<gchar*>("ft"), PX_PER_FT, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }}, - {const_cast<gchar*>("points"), const_cast<gchar*>("pt"), PX_PER_PT, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }}, - {const_cast<gchar*>("picas"), const_cast<gchar*>("pc"), PX_PER_PC, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }}, - {const_cast<gchar*>("pixels"), const_cast<gchar*>("px"), PX_PER_PX, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }}, - {const_cast<gchar*>("meters"), const_cast<gchar*>("m"), PX_PER_M, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }}, -}; -G_DEFINE_TYPE_WITH_CODE (SPRuler, sp_ruler, GTK_TYPE_WIDGET, - G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, - NULL)) +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 void sp_ruler_draw_pos (SPRuler *ruler); +static void sp_ruler_make_pixmap (SPRuler *ruler); + +static PangoLayout * sp_ruler_get_layout (GtkWidget *widget, + const gchar *text); + + +G_DEFINE_TYPE (SPRuler, sp_ruler, GTK_TYPE_WIDGET) + +#define parent_class sp_ruler_parent_class + static void sp_ruler_class_init (SPRulerClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - gobject_class->set_property = sp_ruler_set_property; - gobject_class->get_property = sp_ruler_get_property; + object_class->dispose = sp_ruler_dispose; + object_class->set_property = sp_ruler_set_property; + object_class->get_property = sp_ruler_get_property; - widget_class->realize = sp_ruler_realize; - widget_class->unrealize = sp_ruler_unrealize; + widget_class->realize = sp_ruler_realize; + widget_class->unrealize = sp_ruler_unrealize; + 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_width = sp_ruler_get_preferred_width; widget_class->get_preferred_height = sp_ruler_get_preferred_height; - widget_class->draw = sp_ruler_draw; + 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->expose_event = sp_ruler_expose; + 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->size_allocate = sp_ruler_size_allocate; widget_class->motion_notify_event = sp_ruler_motion_notify; - klass->draw_ticks = sp_ruler_real_draw_ticks; - klass->draw_pos = sp_ruler_real_draw_pos; - - g_object_class_override_property (gobject_class, - PROP_ORIENTATION, - "orientation"); - - g_object_class_install_property (gobject_class, + g_type_class_add_private (object_class, sizeof (SPRulerPrivate)); + + g_object_class_install_property (object_class, + PROP_ORIENTATION, + g_param_spec_enum ("orientation", + _("Orientation"), + _("The orientation of the ruler"), + GTK_TYPE_ORIENTATION, + GTK_ORIENTATION_HORIZONTAL, + static_cast<GParamFlags>(GTK_PARAM_READWRITE))); + + /* FIXME: Should probably use g_param_spec_enum */ + g_object_class_install_property (object_class, + PROP_UNIT, + g_param_spec_uint ("unit", + _("Unit"), + _("Unit of the ruler"), + 0, 8, + SP_PX, + static_cast<GParamFlags>(GTK_PARAM_READWRITE))); + + g_object_class_install_property (object_class, PROP_LOWER, g_param_spec_double ("lower", _("Lower"), @@ -164,7 +213,7 @@ sp_ruler_class_init (SPRulerClass *klass) 0.0, static_cast<GParamFlags>(GTK_PARAM_READWRITE))); - g_object_class_install_property (gobject_class, + g_object_class_install_property (object_class, PROP_UPPER, g_param_spec_double ("upper", _("Upper"), @@ -174,7 +223,7 @@ sp_ruler_class_init (SPRulerClass *klass) 0.0, static_cast<GParamFlags>(GTK_PARAM_READWRITE))); - g_object_class_install_property (gobject_class, + g_object_class_install_property (object_class, PROP_POSITION, g_param_spec_double ("position", _("Position"), @@ -184,7 +233,7 @@ sp_ruler_class_init (SPRulerClass *klass) 0.0, static_cast<GParamFlags>(GTK_PARAM_READWRITE))); - g_object_class_install_property (gobject_class, + g_object_class_install_property (object_class, PROP_MAX_SIZE, g_param_spec_double ("max-size", _("Max Size"), @@ -193,75 +242,65 @@ sp_ruler_class_init (SPRulerClass *klass) G_MAXDOUBLE, 0.0, static_cast<GParamFlags>(GTK_PARAM_READWRITE))); - /** - * SPRuler:metric: - * - * The metric used for the ruler. - * - * TODO: This should probably use g_param_spec_enum - */ - g_object_class_install_property (gobject_class, - PROP_METRIC, - g_param_spec_uint("metric", - _("Metric"), - _("The metric used for the ruler"), - 0, 8, - SP_PX, - static_cast<GParamFlags>(GTK_PARAM_READWRITE))); - g_type_class_add_private (gobject_class, sizeof (SPRulerPrivate)); + gtk_widget_class_install_style_property (widget_class, + g_param_spec_double ("font-scale", + NULL, NULL, + 0.0, + G_MAXDOUBLE, + DEFAULT_RULER_FONT_SCALE, + G_PARAM_READABLE)); } static void sp_ruler_init (SPRuler *ruler) { - ruler->priv = G_TYPE_INSTANCE_GET_PRIVATE(ruler, - SP_TYPE_RULER, - SPRulerPrivate); - - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); - priv->orientation = GTK_ORIENTATION_HORIZONTAL; + gtk_widget_set_has_window (GTK_WIDGET (ruler), FALSE); + priv->orientation = GTK_ORIENTATION_HORIZONTAL; + priv->unit = SP_PX; + priv->lower = 0; + priv->upper = 0; + priv->position = 0; + priv->max_size = 0; priv->backing_store = NULL; - priv->xsrc = 0; - priv->ysrc = 0; - priv->slider_size = 0; - priv->lower = 0; - priv->upper = 0; - priv->position = 0; - priv->max_size = 0; + priv->font_scale = DEFAULT_RULER_FONT_SCALE; - sp_ruler_set_metric(ruler, SP_PX); +#if GTK_CHECK_VERSION(3,0,0) + const gchar *str = + "SPRuler {\n" + " background-color: @bg_color;\n" + "}\n"; + + GtkCssProvider *css = gtk_css_provider_new (); + gtk_css_provider_load_from_data (css, str, -1, NULL); + gtk_style_context_add_provider (gtk_widget_get_style_context (GTK_WIDGET (ruler)), + GTK_STYLE_PROVIDER (css), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + g_object_unref (css); +#endif } - -/** - * sp_ruler_invalidate_ticks: - * @ruler: the ruler to invalidate - * - * For performance reasons, #SPRuler keeps a backbuffer containing the - * prerendered contents of the ticks. To cause a repaint of this buffer, - * call this function instead of gtk_widget_queue_draw(). - **/ -static void sp_ruler_invalidate_ticks(SPRuler *ruler) +static void +sp_ruler_dispose (GObject *object) { - g_return_if_fail(SP_IS_RULER(ruler)); + SPRuler *ruler = SP_RULER (object); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); - if(ruler->priv->backing_store == NULL) - return; + while (priv->track_widgets) + sp_ruler_remove_track_widget (ruler, GTK_WIDGET(priv->track_widgets->data)); - sp_ruler_draw_ticks(ruler); - gtk_widget_queue_draw(GTK_WIDGET(ruler)); + G_OBJECT_CLASS (parent_class)->dispose (object); } /** * sp_ruler_set_range: - * @ruler: the gtkdeprecatedruler + * @ruler: the SPRuler * @lower: the lower limit of the ruler * @upper: the upper limit of the ruler - * @position: the mark on the ruler * @max_size: the maximum size of the ruler used when calculating the space to * leave for the text * @@ -269,14 +308,15 @@ static void sp_ruler_invalidate_ticks(SPRuler *ruler) */ void sp_ruler_set_range (SPRuler *ruler, - gdouble lower, - gdouble upper, - gdouble position, - gdouble max_size) + gdouble lower, + gdouble upper, + gdouble max_size) { + SPRulerPrivate *priv; + g_return_if_fail (SP_IS_RULER (ruler)); - SPRulerPrivate *priv = ruler->priv; + priv = SP_RULER_GET_PRIVATE (ruler); g_object_freeze_notify (G_OBJECT (ruler)); if (priv->lower != lower) @@ -289,11 +329,6 @@ sp_ruler_set_range (SPRuler *ruler, priv->upper = upper; g_object_notify (G_OBJECT (ruler), "upper"); } - if (priv->position != position) - { - priv->position = position; - g_object_notify (G_OBJECT (ruler), "position"); - } if (priv->max_size != max_size) { priv->max_size = max_size; @@ -301,7 +336,7 @@ sp_ruler_set_range (SPRuler *ruler, } g_object_thaw_notify (G_OBJECT (ruler)); - sp_ruler_invalidate_ticks(ruler); + gtk_widget_queue_draw (GTK_WIDGET (ruler)); } /** @@ -309,7 +344,6 @@ sp_ruler_set_range (SPRuler *ruler, * @ruler: a #SPRuler * @lower: (allow-none): location to store lower limit of the ruler, or %NULL * @upper: (allow-none): location to store upper limit of the ruler, or %NULL - * @position: (allow-none): location to store the current position of the mark on the ruler, or %NULL * @max_size: location to store the maximum size of the ruler used when calculating * the space to leave for the text, or %NULL. * @@ -320,19 +354,18 @@ void sp_ruler_get_range (SPRuler *ruler, gdouble *lower, gdouble *upper, - gdouble *position, gdouble *max_size) { + SPRulerPrivate *priv; + g_return_if_fail (SP_IS_RULER (ruler)); - SPRulerPrivate *priv = ruler->priv; + priv = SP_RULER_GET_PRIVATE (ruler); if (lower) *lower = priv->lower; if (upper) *upper = priv->upper; - if (position) - *position = priv->position; if (max_size) *max_size = priv->max_size; } @@ -344,7 +377,7 @@ sp_ruler_set_property (GObject *object, GParamSpec *pspec) { SPRuler *ruler = SP_RULER (object); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); switch (prop_id) { @@ -352,25 +385,35 @@ sp_ruler_set_property (GObject *object, priv->orientation = static_cast<GtkOrientation>(g_value_get_enum (value)); gtk_widget_queue_resize (GTK_WIDGET (ruler)); break; + + case PROP_UNIT: + sp_ruler_set_unit (ruler, static_cast<SPMetric>(g_value_get_int (value))); + break; + case PROP_LOWER: - sp_ruler_set_range (ruler, g_value_get_double (value), priv->upper, - priv->position, priv->max_size); + sp_ruler_set_range (ruler, + g_value_get_double (value), + priv->upper, + priv->max_size); break; case PROP_UPPER: - sp_ruler_set_range (ruler, priv->lower, g_value_get_double (value), - priv->position, priv->max_size); + sp_ruler_set_range (ruler, + priv->lower, + g_value_get_double (value), + priv->max_size); break; + case PROP_POSITION: - sp_ruler_set_range (ruler, priv->lower, priv->upper, - g_value_get_double (value), priv->max_size); + sp_ruler_set_position (ruler, g_value_get_double (value)); break; + case PROP_MAX_SIZE: - sp_ruler_set_range (ruler, priv->lower, priv->upper, - priv->position, g_value_get_double (value)); - break; - case PROP_METRIC: - sp_ruler_set_metric(ruler, static_cast<SPMetric>(g_value_get_enum (value))); + sp_ruler_set_range (ruler, + priv->lower, + priv->upper, + g_value_get_double (value)); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -384,13 +427,17 @@ sp_ruler_get_property (GObject *object, GParamSpec *pspec) { SPRuler *ruler = SP_RULER (object); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); switch (prop_id) { case PROP_ORIENTATION: g_value_set_enum (value, priv->orientation); break; + + case PROP_UNIT: + g_value_set_int (value, priv->unit); + break; case PROP_LOWER: g_value_set_double (value, priv->lower); break; @@ -403,262 +450,326 @@ sp_ruler_get_property (GObject *object, case PROP_MAX_SIZE: g_value_set_double (value, priv->max_size); break; - case PROP_METRIC: - g_value_set_enum(value, sp_ruler_get_metric(ruler)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } - -/** - * sp_ruler_get_metric: - * @ruler: a #SPRuler - * - * Gets the units used for a #SPRuler. See sp_ruler_set_metric(). - * - * Return value: the units currently used for @ruler - **/ -SPMetric sp_ruler_get_metric(SPRuler *ruler) +static void +sp_ruler_realize (GtkWidget *widget) { - g_return_val_if_fail(SP_IS_RULER(ruler), static_cast<SPMetric>(0)); - SPRulerPrivate *priv = ruler->priv; + SPRuler *ruler = SP_RULER (widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkAllocation allocation; + GdkWindowAttr attributes; + gint attributes_mask; - for (size_t i = 0; i < G_N_ELEMENTS(sp_ruler_metrics); i++) { - if (priv->metric == &sp_ruler_metrics[i]) { - return static_cast<SPMetric>(i); - } - } - - g_assert_not_reached (); - - return static_cast<SPMetric>(0); -} - - -static void sp_ruler_draw_ticks(SPRuler *ruler) -{ - g_return_if_fail(SP_IS_RULER(ruler)); - SPRulerPrivate *priv = ruler->priv; + GTK_WIDGET_CLASS (sp_ruler_parent_class)->realize (widget); + + gtk_widget_get_allocation (widget, &allocation); + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = allocation.x; + attributes.y = allocation.y; + attributes.width = allocation.width; + attributes.height = allocation.height; + attributes.wclass = GDK_INPUT_ONLY; #if GTK_CHECK_VERSION(3,0,0) - cairo_t *cr = cairo_create(priv->backing_store); + attributes.event_mask = (gtk_widget_get_events (widget) | + GDK_EXPOSURE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK); #else - cairo_t *cr = gdk_cairo_create(priv->backing_store); + attributes.event_mask = (gtk_widget_get_events (widget) | + GDK_EXPOSURE_MASK | + GDK_POINTER_MOTION_MASK); #endif - if (SP_RULER_GET_CLASS(ruler)->draw_ticks) - SP_RULER_GET_CLASS(ruler)->draw_ticks(ruler, cr); + attributes_mask = GDK_WA_X | GDK_WA_Y; - cairo_destroy(cr); -} + priv->input_window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (priv->input_window, ruler); + sp_ruler_make_pixmap (ruler); +} -static void sp_ruler_realize(GtkWidget *widget) +static void +sp_ruler_unrealize(GtkWidget *widget) { - GtkAllocation allocation; - SPRuler *ruler; - GdkWindow *window; - GdkWindowAttr attributes; - gint attributes_mask; + SPRuler *ruler = SP_RULER (widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); - ruler = SP_RULER (widget); + if (priv->backing_store) + { + cairo_surface_destroy (priv->backing_store); + priv->backing_store = NULL; + } + + if (priv->layout) + { + g_object_unref (priv->layout); + priv->layout = NULL; + } - gtk_widget_set_realized (widget, TRUE); + if (priv->input_window) + { + gdk_window_destroy (priv->input_window); + priv->input_window = NULL; + } - gtk_widget_get_allocation(widget, &allocation); + GTK_WIDGET_CLASS (sp_ruler_parent_class)->unrealize (widget); +} - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = allocation.x; - attributes.y = allocation.y; - attributes.width = allocation.width; - attributes.height = allocation.height; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= (GDK_EXPOSURE_MASK | - GDK_POINTER_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK); - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; - - window = gdk_window_new(gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gtk_widget_set_window(widget, window); - gdk_window_set_user_data(window, ruler); +static void +sp_ruler_map (GtkWidget *widget) +{ + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); -#if GTK_CHECK_VERSION(3,0,0) - gtk_style_context_set_background(gtk_widget_get_style_context(widget), - window); -#else - gtk_widget_style_attach(widget); - gtk_style_set_background(gtk_widget_get_style(widget), - window, GTK_STATE_ACTIVE); -#endif + GTK_WIDGET_CLASS (sp_ruler_parent_class)->map (widget); - sp_ruler_make_pixmap (ruler); + if (priv->input_window) + gdk_window_show (priv->input_window); } -static void sp_ruler_unrealize(GtkWidget *widget) +static void +sp_ruler_unmap (GtkWidget *widget) { - SPRuler *ruler = SP_RULER (widget); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); - if (priv->backing_store) + if (priv->input_window) + gdk_window_hide (priv->input_window); + + GTK_WIDGET_CLASS (sp_ruler_parent_class)->unmap (widget); +} + +static void +sp_ruler_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + SPRuler *ruler = SP_RULER(widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkAllocation widget_allocation; + gboolean resized; + + gtk_widget_get_allocation (widget, &widget_allocation); + + resized = (widget_allocation.width != allocation->width || + widget_allocation.height != allocation->height); + + gtk_widget_set_allocation(widget, allocation); + + if (gtk_widget_get_realized (widget)) { -#if GTK_CHECK_VERSION(3,0,0) - cairo_surface_destroy(priv->backing_store); -#else - g_object_unref(priv->backing_store); -#endif - priv->backing_store = NULL; + gdk_window_move_resize (priv->input_window, + allocation->x, allocation->y, + allocation->width, allocation->height); + + if (resized) + sp_ruler_make_pixmap (ruler); } - - GTK_WIDGET_CLASS (sp_ruler_parent_class)->unrealize (widget); } -static void sp_ruler_size_request(GtkWidget *widget, - GtkRequisition *requisition) +static void +sp_ruler_size_request (GtkWidget *widget, + GtkRequisition *requisition) { - SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); - GtkStyle *style = gtk_widget_get_style(widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); + PangoLayout *layout; + PangoRectangle ink_rect; + gint size; + + layout = sp_ruler_get_layout (widget, "0123456789"); + pango_layout_get_pixel_extents (layout, &ink_rect, NULL); + + 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); + + 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 + RULER_WIDTH; + requisition->height = style->ythickness * 2 + size; +#endif } else { - requisition->width = style->xthickness * 2 + RULER_WIDTH; +#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) -static void sp_ruler_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width) +sp_ruler_style_updated (GtkWidget *widget) +#else +sp_ruler_style_set (GtkWidget *widget, + GtkStyle *prev_style) +#endif { - GtkRequisition requisition; - sp_ruler_size_request(widget, &requisition); - *minimal_width = *natural_width = requisition.width; + 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, + NULL); + + if (priv->layout) + { + g_object_unref (priv->layout); + priv->layout = NULL; + } } -static void sp_ruler_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height) +#if GTK_CHECK_VERSION(3,0,0) +static void +sp_ruler_get_preferred_width (GtkWidget *widget, + gint *minimum_width, + gint *natural_width) { - GtkRequisition requisition; - sp_ruler_size_request(widget, &requisition); - *minimal_height = *natural_height = requisition.height; + GtkRequisition requisition; + + sp_ruler_size_request (widget, &requisition); + + *minimum_width = *natural_width = requisition.width; } -#endif -static void sp_ruler_size_allocate(GtkWidget *widget, GtkAllocation *allocation) +static void +sp_ruler_get_preferred_height (GtkWidget *widget, + gint *minimum_height, + gint *natural_height) { - SPRuler *ruler = SP_RULER(widget); - GtkAllocation old_allocation; - gtk_widget_get_allocation(widget, &old_allocation); + GtkRequisition requisition; + + sp_ruler_size_request(widget, &requisition); + + *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); - gboolean resized = (old_allocation.width != allocation->width || - old_allocation.height != allocation->height); + gtk_widget_get_allocation (widget, &allocation); + cairo_translate (cr, allocation.x, allocation.y); - gtk_widget_set_allocation(widget, allocation); + gboolean result = sp_ruler_draw (widget, cr); - if (gtk_widget_get_realized (widget)) - { - gdk_window_move_resize(gtk_widget_get_window(widget), - allocation->x, allocation->y, - allocation->width, allocation->height); + cairo_destroy (cr); - if(resized) - sp_ruler_make_pixmap (ruler); - } + return result; } - -#if GTK_CHECK_VERSION(3,0,0) -static gboolean sp_ruler_draw(GtkWidget *widget, - cairo_t *cr) -#else -static gboolean sp_ruler_expose(GtkWidget *widget, - GdkEventExpose *event) #endif + +static gboolean +sp_ruler_draw (GtkWidget *widget, + cairo_t *cr) { - SPRuler *ruler = SP_RULER (widget); - SPRulerPrivate *priv = ruler->priv; + SPRuler *ruler = SP_RULER (widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + + sp_ruler_draw_ticks (ruler); -#if GTK_CHECK_VERSION(3,0,0) cairo_set_source_surface(cr, priv->backing_store, 0, 0); cairo_paint(cr); -#else - cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); - gdk_cairo_set_source_pixmap(cr, priv->backing_store, 0, 0); - gdk_cairo_region(cr, event->region); - cairo_fill(cr); -#endif - - if (SP_RULER_GET_CLASS(ruler)->draw_pos) - SP_RULER_GET_CLASS(ruler)->draw_pos(ruler, cr); -#if !GTK_CHECK_VERSION(3,0,0) - cairo_destroy (cr); -#endif + sp_ruler_draw_pos (ruler); return FALSE; } -static void sp_ruler_make_pixmap(SPRuler *ruler) +static void +sp_ruler_make_pixmap (SPRuler *ruler) { - SPRulerPrivate *priv = ruler->priv; - GtkWidget *widget = GTK_WIDGET(ruler); + GtkWidget *widget = GTK_WIDGET (ruler); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkAllocation allocation; - GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); if (priv->backing_store) -#if GTK_CHECK_VERSION(3,0,0) - cairo_surface_destroy(priv->backing_store); + cairo_surface_destroy (priv->backing_store); - priv->backing_store = gdk_window_create_similar_surface(gtk_widget_get_window(widget), - CAIRO_CONTENT_COLOR, - allocation.width, - allocation.height); -#else - g_object_unref(priv->backing_store); - - priv->backing_store = gdk_pixmap_new(gtk_widget_get_window(widget), - allocation.width, - allocation.height, - -1); -#endif - - priv->xsrc = 0; - priv->ysrc = 0; - - sp_ruler_draw_ticks(ruler); + priv->backing_store = + gdk_window_create_similar_surface (gtk_widget_get_window (widget), + CAIRO_CONTENT_COLOR, + allocation.width, + allocation.height); } - -static void sp_ruler_real_draw_pos(SPRuler *ruler, - cairo_t *cr) +static void +sp_ruler_draw_pos (SPRuler *ruler) { - GtkAllocation allocation; - GtkWidget *widget = GTK_WIDGET (ruler); - SPRulerPrivate *priv = ruler->priv; - gint x, y; - gint bs_width, bs_height; - gdouble increment; + 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; + gint x, y; + gint width, height; + gint bs_width, bs_height; + + if (! gtk_widget_is_drawable (widget)) + return; - GtkStyle *style = gtk_widget_get_style(widget); gtk_widget_get_allocation(widget, &allocation); - gint xthickness = style->xthickness; - gint ythickness = style->ythickness; - gint width = allocation.width; - gint height = allocation.height; +#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 if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { - height -= ythickness * 2; + width = allocation.width; +#if GTK_CHECK_VERSION(3,0,0) + height = allocation.height - (border.top + border.bottom); +#else + height = allocation.height - ythickness * 2; +#endif bs_width = height / 2 + 2; bs_width |= 1; /* make sure it's odd */ @@ -666,7 +777,12 @@ static void sp_ruler_real_draw_pos(SPRuler *ruler, } else { - width -= xthickness * 2; +#if GTK_CHECK_VERSION(3,0,0) + width = allocation.width - (border.left + border.right); +#else + width = allocation.width - xthickness * 2; +#endif + height = allocation.height; bs_height = width / 2 + 2; bs_height |= 1; /* make sure it's odd */ @@ -675,22 +791,63 @@ static void sp_ruler_real_draw_pos(SPRuler *ruler, if ((bs_width > 0) && (bs_height > 0)) { + cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (widget)); + gdouble lower; + gdouble upper; + gdouble position; + gdouble increment; + + cairo_rectangle (cr, + allocation.x, allocation.y, + allocation.width, allocation.height); + cairo_clip (cr); + + cairo_translate (cr, allocation.x, allocation.y); + + /* If a backing store exists, restore the ruler */ + if (priv->backing_store) + { + cairo_set_source_surface (cr, priv->backing_store, 0, 0); + cairo_rectangle (cr, priv->xsrc, priv->ysrc, bs_width, bs_height); + cairo_fill (cr); + } + + position = sp_ruler_get_position (ruler); + + sp_ruler_get_range (ruler, &lower, &upper, NULL); + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { - increment = (gdouble) width / (priv->upper - priv->lower); + increment = (gdouble) width / (upper - lower); - x = ROUND ((priv->position - priv->lower) * increment) + (xthickness - bs_width) / 2 - 1; +#if GTK_CHECK_VERSION(3,0,0) + x = ROUND ((position - lower) * increment) + (border.left - bs_width) / 2 - 1; + y = (height + bs_height) / 2 + border.top; +#else + x = ROUND ((position - lower) * increment) + (xthickness - bs_width) / 2 - 1; y = (height + bs_height) / 2 + ythickness; +#endif } else { - increment = (gdouble) height / (priv->upper - priv->lower); + increment = (gdouble) height / (upper - lower); +#if GTK_CHECK_VERSION(3,0,0) + x = (width + bs_width) / 2 + border.left; + y = ROUND ((position - lower) * increment) + (border.top - bs_height) / 2 - 1; +#else x = (width + bs_width) / 2 + xthickness; - y = ROUND ((priv->position - priv->lower) * increment) + (ythickness - bs_height) / 2 - 1; + y = ROUND ((position - lower) * increment) + (ythickness - bs_height) / 2 - 1; +#endif } - gdk_cairo_set_source_color(cr, &style->fg[gtk_widget_get_state(widget)]); +#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, x, y); @@ -707,246 +864,636 @@ static void sp_ruler_real_draw_pos(SPRuler *ruler, cairo_fill (cr); + cairo_destroy (cr); + priv->xsrc = x; priv->ysrc = y; } } +/** + * sp_ruler_new: + * @orientation: the ruler's orientation + * + * Creates a new ruler. + * + * Return value: a new #SPRuler widget. + */ +GtkWidget * +sp_ruler_new (GtkOrientation orientation) +{ + return GTK_WIDGET (g_object_new (SP_TYPE_RULER, + "orientation", orientation, + NULL)); +} + +static void +sp_ruler_update_position (SPRuler *ruler, + gdouble x, + gdouble y) +{ + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkAllocation allocation; + gdouble lower; + gdouble upper; + + gtk_widget_get_allocation (GTK_WIDGET (ruler), &allocation); + sp_ruler_get_range (ruler, &lower, &upper, NULL); + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + sp_ruler_set_position (ruler, + lower + + (upper - lower) * x / allocation.width); + } + else + { + sp_ruler_set_position (ruler, + lower + + (upper - lower) * y / allocation.height); + } +} + +/* 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_effective_parent (w)) + { + gdouble px, py; + + gdk_window_coords_to_parent (w, *x, *y, &px, &py); + + *x += px; + *y += px; + } + + if (w == NULL) + { + *x = 0; + *y = 0; + return FALSE; + } + + return TRUE; +} + +static void +sp_ruler_event_to_widget_coords (GtkWidget *widget, + GdkWindow *window, + gdouble event_x, + gdouble event_y, + gint *widget_x, + gint *widget_y) +{ + gint tx, ty; -#define UNUSED_PIXELS 2 // There appear to be two pixels that are not being used at each end of the ruler + 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; +} -GtkWidget* sp_ruler_new(GtkOrientation orientation) +static gboolean +sp_ruler_track_widget_motion_notify (GtkWidget *widget, + GdkEventMotion *mevent, + SPRuler *ruler) { - return GTK_WIDGET(g_object_new(SP_TYPE_RULER, - "orientation", orientation, - NULL)); + gint widget_x; + gint widget_y; + gint ruler_x; + gint ruler_y; + + widget = gtk_get_event_widget (reinterpret_cast<GdkEvent *>(mevent)); + + sp_ruler_event_to_widget_coords (widget, mevent->window, + mevent->x, mevent->y, + &widget_x, &widget_y); + + if (gtk_widget_translate_coordinates (widget, GTK_WIDGET (ruler), + widget_x, widget_y, + &ruler_x, &ruler_y)) + { + sp_ruler_update_position (ruler, ruler_x, ruler_y); + } + + return FALSE; } -static gboolean sp_ruler_motion_notify(GtkWidget *widget, - GdkEventMotion *event) +void +sp_ruler_add_track_widget (SPRuler *ruler, + GtkWidget *widget) { - GtkAllocation allocation; - SPRuler *ruler = SP_RULER(widget); - SPRulerPrivate *priv = ruler->priv; - - gdk_event_request_motions(event); - gint x = event->x; - gint y = event->y; - - gtk_widget_get_allocation(widget, &allocation); + SPRulerPrivate *priv; + + g_return_if_fail (SP_IS_RULER (ruler)); + g_return_if_fail (GTK_IS_WIDGET (ruler)); + + priv = SP_RULER_GET_PRIVATE (ruler); - if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) - priv->position = priv->lower + (priv->upper - priv->lower) * (x + UNUSED_PIXELS) / (allocation.width + 2*UNUSED_PIXELS); - else - priv->position = priv->lower + (priv->upper - priv->lower) * (y + UNUSED_PIXELS) / (allocation.height + 2*UNUSED_PIXELS); + g_return_if_fail (g_list_find (priv->track_widgets, widget) == NULL); - g_object_notify(G_OBJECT(ruler), "position"); + priv->track_widgets = g_list_prepend (priv->track_widgets, widget); - gtk_widget_queue_draw(widget); + g_signal_connect (widget, "motion-notify-event", + G_CALLBACK (sp_ruler_track_widget_motion_notify), + ruler); + g_signal_connect (widget, "destroy", + G_CALLBACK (sp_ruler_remove_track_widget), + ruler); +} - return FALSE; +/** + * sp_ruler_remove_track_widget: + * @ruler: an #SPRuler + * @widget: the track widget to remove + * + * Removes a previously added track widget from the ruler. See + * sp_ruler_add_track_widget(). + */ +void +sp_ruler_remove_track_widget (SPRuler *ruler, + GtkWidget *widget) +{ + SPRulerPrivate *priv; + + g_return_if_fail (SP_IS_RULER (ruler)); + g_return_if_fail (GTK_IS_WIDGET (ruler)); + + priv = SP_RULER_GET_PRIVATE (ruler); + + g_return_if_fail (g_list_find (priv->track_widgets, widget) != NULL); + + priv->track_widgets = g_list_remove (priv->track_widgets, widget); + + g_signal_handlers_disconnect_by_func (widget, + (gpointer) G_CALLBACK (sp_ruler_track_widget_motion_notify), + ruler); + g_signal_handlers_disconnect_by_func (widget, + (gpointer) G_CALLBACK (sp_ruler_remove_track_widget), + ruler); } -static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) +/** + * sp_ruler_set_unit: + * @ruler: a #SPRuler + * @unit: the #SPMetric to set the ruler to + * + * This sets the unit of the ruler. + */ +void +sp_ruler_set_unit (SPRuler *ruler, + SPMetric unit) { - SPRulerPrivate *priv = ruler->priv; - gint width = 0; - gint height = 0; - gchar unit_str[32]; - gchar digit_str[2] = { '\0', '\0' }; - GtkOrientation orientation; - GtkAllocation allocation; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + + g_return_if_fail (SP_IS_RULER (ruler)); - g_return_if_fail (ruler != NULL); + if (priv->unit != unit) + { + priv->unit = unit; + g_object_notify(G_OBJECT(ruler), "unit"); + + gtk_widget_queue_draw (GTK_WIDGET (ruler)); + } +} + +/** + * sp_ruler_get_unit: + * @ruler: a #SPRuler + * + * Return value: the unit currently used in the @ruler widget. + **/ +SPMetric +sp_ruler_get_unit (SPRuler *ruler) +{ + g_return_val_if_fail(SP_IS_RULER(ruler), static_cast<SPMetric>(0)); - g_object_get(G_OBJECT(ruler), "orientation", &orientation, NULL); - GtkWidget *widget = GTK_WIDGET (ruler); + return SP_RULER_GET_PRIVATE (ruler)->unit; +} - PangoContext *pango_context = gtk_widget_get_pango_context (widget); - PangoLayout *pango_layout = pango_layout_new (pango_context); - PangoFontDescription *fs = pango_font_description_new (); - pango_font_description_set_size (fs, RULER_FONT_SIZE); - pango_layout_set_font_description (pango_layout, fs); - pango_font_description_free (fs); +/** + * sp_ruler_set_position: + * @ruler: a #SPRuler + * @position: the position to set the ruler to + * + * This sets the position of the ruler. + */ +void +sp_ruler_set_position (SPRuler *ruler, + gdouble position) +{ + SPRulerPrivate *priv; - gint digit_height = (int) floor (RULER_FONT_SIZE * RULER_FONT_VERTICAL_SPACING / PANGO_SCALE + 0.5); + g_return_if_fail (SP_IS_RULER (ruler)); + priv = SP_RULER_GET_PRIVATE (ruler); + + if (priv->position != position) + { + priv->position = position; + g_object_notify (G_OBJECT (ruler), "position"); + + sp_ruler_draw_pos (ruler); + } +} + +/** + * sp_ruler_get_position: + * @ruler: a #SPRuler + * + * Return value: the current position of the @ruler widget. + */ +gdouble +sp_ruler_get_position (SPRuler *ruler) +{ + g_return_val_if_fail (SP_IS_RULER (ruler), 0.0); + + return SP_RULER_GET_PRIVATE (ruler)->position; +} + +static gboolean +sp_ruler_motion_notify (GtkWidget *widget, + GdkEventMotion *event) +{ + SPRuler *ruler = SP_RULER(widget); + + sp_ruler_update_position (ruler, event->x, event->y); + + return FALSE; +} + +static void +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); - GtkStateFlags state = gtk_widget_get_state_flags(widget); - GtkBorder padding; - gtk_style_context_get_padding(context, state, &padding); - gint xthickness = padding.left; - gint ythickness = padding.top; + GtkStyleContext *context = gtk_widget_get_style_context (widget); + GtkBorder border; + GdkRGBA color; #else - GtkStyle *style = gtk_widget_get_style(widget); - gint xthickness = style->xthickness; - gint ythickness = style->ythickness; + 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; + cairo_t *cr; + gint i; + gint width, height; + gint length, ideal_length; + gdouble lower, upper; /* Upper and lower limits, in ruler units */ + gdouble increment; /* Number of pixels per unit */ + guint scale; /* Number of units per major unit */ + gdouble start, end, cur; + gchar unit_str[32]; + gint digit_height; + gint digit_offset; + gchar digit_str[2] = { '\0', '\0' }; + gint text_size; + gint pos; + gdouble max_size; + SPMetric unit; + SPRulerMetric ruler_metric = ruler_metric_general; /* The metric to use for this unit system */ + PangoLayout *layout; + PangoRectangle logical_rect, ink_rect; + + if (! gtk_widget_is_drawable (widget)) + return; + 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 + + layout = sp_ruler_get_layout (widget, "0123456789"); + pango_layout_get_extents (layout, &ink_rect, &logical_rect); - if (orientation == GTK_ORIENTATION_HORIZONTAL) { - width = allocation.width; // in pixels; is apparently 2 pixels shorter than the canvas at each end - height = allocation.height; - } else { - width = allocation.height; - height = allocation.width; - } + digit_height = PANGO_PIXELS (ink_rect.height) + 2; + digit_offset = ink_rect.y; + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + width = allocation.width; #if GTK_CHECK_VERSION(3,0,0) - gtk_render_frame(context, - cr, - 0, 0, - allocation.width, allocation.height); - - gtk_render_background(context, - cr, - 0, 0, - allocation.width, allocation.height); + height = allocation.height - (border.top + border.bottom); #else - gtk_paint_box(style, priv->backing_store, - GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, widget, - orientation == GTK_ORIENTATION_HORIZONTAL ? "hruler" : "vruler", - 0, 0, - allocation.width, allocation.height); + height = allocation.height - ythickness * 2; #endif - - cairo_set_line_width(cr, 1.0); + } + 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) - GdkRGBA color; - gtk_style_context_get_color(context, - gtk_widget_get_state_flags(widget), - &color); - gdk_cairo_set_source_rgba(cr, &color); + gtk_render_background (context, cr, 0, 0, allocation.width, allocation.height); + gtk_render_frame (context, cr, 0, 0, allocation.width, allocation.height); + + gtk_style_context_get_color (context, gtk_widget_get_state_flags (widget), + &color); + gdk_cairo_set_source_rgba (cr, &color); + + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + cairo_rectangle (cr, + border.left, + height + border.top, + allocation.width - (border.left + border.right), + 1); + } + else + { + cairo_rectangle (cr, + height + border.left, + border.top, + 1, + allocation.height - (border.top + border.bottom)); + } #else - gdk_cairo_set_source_color(cr, &style->fg[gtk_widget_get_state(widget)]); + 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 - gdouble upper = priv->upper / priv->metric->pixels_per_unit; // upper and lower are expressed in ruler units - gdouble lower = priv->lower / priv->metric->pixels_per_unit; - /* "pixels_per_unit" should be "points_per_unit". This is the size of the unit - * in 1/72nd's of an inch and has nothing to do with screen pixels */ + sp_ruler_get_range (ruler, &lower, &upper, &max_size); if ((upper - lower) == 0) - return; + goto out; - double increment = (double) (width + 2*UNUSED_PIXELS) / (upper - lower); // screen pixels per ruler unit + increment = (gdouble) width / (upper - lower); /* determine the scale - * For vruler, use the maximum extents of the ruler to determine the largest - * possible number to be displayed. Calculate the height in pixels - * of this displayed text. Use this height to find a scale which - * leaves sufficient room for drawing the ruler. - * For hruler, we calculate the text size as for the vruler instead of using - * text_width = gdk_string_width(font, unit_str), so that the result - * for the scale looks consistent with an accompanying vruler + * Use the maximum extents of the ruler to determine the largest + * possible number to be displayed. Calculate the height in pixels + * of this displayed text. Use this height to find a scale which + * leaves sufficient room for drawing the ruler. + * + * We calculate the text size as for the vruler instead of + * actually measuring the text width, so that the result for the + * scale looks consistent with an accompanying vruler */ - gint scale = (int)(ceil(priv->max_size / priv->metric->pixels_per_unit)); + scale = ceil (priv->max_size); sprintf (unit_str, "%d", scale); - gint text_dimension = strlen (unit_str) * digit_height + 1; + text_size = strlen (unit_str) * digit_height + 1; + + /* Inkscape change to ruler: Use a 1,2,4,8... scale for inches + * or a 1,2,5,10... scale for everything else */ + if (sp_ruler_get_unit (ruler) == SP_IN) + ruler_metric = ruler_metric_inches; - for (scale = 0; scale < MAXIMUM_SCALES; scale++) - if (priv->metric->ruler_scale[scale] * fabs(increment) > 2 * text_dimension) + for (scale = 0; scale < G_N_ELEMENTS (ruler_metric.ruler_scale); scale++) + if (ruler_metric.ruler_scale[scale] * fabs (increment) > 2 * text_size) break; - if (scale == MAXIMUM_SCALES) - scale = MAXIMUM_SCALES - 1; + if (scale == G_N_ELEMENTS (ruler_metric.ruler_scale)) + scale = G_N_ELEMENTS (ruler_metric.ruler_scale) - 1; + + unit = sp_ruler_get_unit (ruler); /* drawing starts here */ - gint length = 0; - for (gint i = MAXIMUM_SUBDIVIDE - 1; i >= 0; i--) { - double subd_incr = priv->metric->ruler_scale[scale] / - priv->metric->subdivide[i]; - if (subd_incr * fabs(increment) <= MINIMUM_INCR) + length = 0; + for (i = G_N_ELEMENTS (ruler_metric.subdivide) - 1; i >= 0; i--) + { + gdouble subd_incr; + + /* hack to get proper subdivisions at full pixels */ + if (unit == SP_PX && scale == 1 && i == 1) + subd_incr = 1.0; + else + subd_incr = ((gdouble) ruler_metric.ruler_scale[scale] / + (gdouble) ruler_metric.subdivide[i]); + + if (subd_incr * fabs (increment) <= MINIMUM_INCR) continue; /* Calculate the length of the tickmarks. Make sure that * this length increases for each set of ticks */ - gint ideal_length = height / (i + 1) - 1; + ideal_length = height / (i + 1) - 1; if (ideal_length > ++length) length = ideal_length; - gdouble start = 0; - gdouble end = 0; - if (lower < upper) { + if (lower < upper) + { start = floor (lower / subd_incr) * subd_incr; end = ceil (upper / subd_incr) * subd_incr; - } else { + } + else + { start = floor (upper / subd_incr) * subd_incr; end = ceil (lower / subd_incr) * subd_incr; - } + } gint tick_index = 0; - gdouble cur = start; // location (in ruler units) of the first invisible tick at the left side of the canvas - while (cur <= end) { + for (cur = start; cur <= end; cur += subd_incr) + { // due to the typical values for cur, lower and increment, pos will often end up to // 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 ;-)) - gint pos = int(Inkscape::round((cur - lower) * increment + 1e-12)) - UNUSED_PIXELS; + pos = gint(Inkscape::round((cur - lower) * increment + 1e-12)); - if (orientation == GTK_ORIENTATION_HORIZONTAL) { - cairo_move_to(cr, pos+0.5, height + ythickness); - cairo_line_to(cr, pos+0.5, height - length + ythickness); - } else { - cairo_move_to(cr, height + xthickness - length, pos+0.5); - cairo_line_to(cr, height + xthickness, pos+0.5); - } +#if GTK_CHECK_VERSION(3,0,0) + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + cairo_rectangle (cr, + pos, height + border.top - length, + 1, length); + } + else + { + cairo_rectangle (cr, + 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)priv->metric->ruler_scale[scale])/priv->metric->subdivide[i]); + double label_spacing_px = fabs(increment*(double)ruler_metric.ruler_scale[scale]/ruler_metric.subdivide[i]); if (i == 0 && (label_spacing_px > 6*digit_height || tick_index%2 == 0 || cur == 0) && (label_spacing_px > 3*digit_height || tick_index%4 == 0 || cur == 0)) - { + { if (fabs((int)cur) >= 2000 && (((int) cur)/1000)*1000 == ((int) cur)) sprintf (unit_str, "%dk", ((int) cur)/1000); else sprintf (unit_str, "%d", (int) cur); - if (orientation == GTK_ORIENTATION_HORIZONTAL) { - pango_layout_set_text (pango_layout, unit_str, -1); - cairo_move_to(cr, pos+2, 0); - pango_cairo_show_layout(cr, pango_layout); - } else { - for (gint j = 0; j < (int) strlen (unit_str); j++) { + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + 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); + } + else + { + gint j; + + for (j = 0; j < (int) strlen (unit_str); j++) + { digit_str[0] = unit_str[j]; - pango_layout_set_text (pango_layout, digit_str, 1); - cairo_move_to(cr, xthickness + 1, pos + digit_height * (j) + 1); - pango_cairo_show_layout(cr, pango_layout); - } - } - - } - /* Calculate cur from start rather than incrementing by subd_incr - * in each iteration. This is to avoid propagation of floating point - * errors in subd_incr. - */ + 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); + } + } + } + ++tick_index; - cur = start + tick_index * subd_incr; - cairo_stroke(cr); - } - } -} + } + } + cairo_fill (cr); -void sp_ruler_set_metric(SPRuler *ruler, SPMetric metric) +out: + cairo_destroy (cr); +} + +static PangoLayout* +sp_ruler_create_layout (GtkWidget *widget, + const gchar *text) { - g_return_if_fail(ruler != NULL); - g_return_if_fail(SP_IS_RULER (ruler)); - g_return_if_fail((unsigned) metric < G_N_ELEMENTS(sp_ruler_metrics)); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); + PangoLayout *layout; + PangoAttrList *attrs; + PangoAttribute *attr; - if (metric == 0) - return; + layout = gtk_widget_create_pango_layout (widget, text); - priv->metric = const_cast<SPRulerMetric *>(&sp_ruler_metrics[metric]); + attrs = pango_attr_list_new (); - g_object_notify(G_OBJECT(ruler), "metric"); + attr = pango_attr_scale_new (priv->font_scale); + attr->start_index = 0; + attr->end_index = -1; + pango_attr_list_insert (attrs, attr); - sp_ruler_invalidate_ticks(ruler); + pango_layout_set_attributes (layout, attrs); + pango_attr_list_unref (attrs); + + return layout; +} + +static PangoLayout * +sp_ruler_get_layout (GtkWidget *widget, + const gchar *text) +{ + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); + + if (priv->layout) + { + pango_layout_set_text (priv->layout, text, -1); + return priv->layout; + } + + priv->layout = sp_ruler_create_layout (widget, text); + + return priv->layout; } + +/* + 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/ruler.h b/src/widgets/ruler.h index d4e21b300..f0d866fff 100644 --- a/src/widgets/ruler.h +++ b/src/widgets/ruler.h @@ -18,6 +18,8 @@ #include <iostream> #include <glib.h> +G_BEGIN_DECLS + #define SP_TYPE_RULER (sp_ruler_get_type ()) #define SP_RULER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_RULER, SPRuler)) #define SP_RULER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_RULER, SPRulerClass)) @@ -25,59 +27,45 @@ #define SP_IS_RULER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_RULER)) #define SP_RULER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SP_TYPE_RULER, SPRulerClass)) - typedef struct _SPRuler SPRuler; -typedef struct _SPRulerPrivate SPRulerPrivate; typedef struct _SPRulerClass SPRulerClass; -typedef struct _SPRulerMetric SPRulerMetric; -/* All distances below are in 1/72nd's of an inch. (According to - * Adobe that's a point, but points are really 1/72.27 in.) - */ struct _SPRuler { - GtkWidget widget; - - /*< private >*/ - SPRulerPrivate *priv; + GtkWidget parent_instance; }; struct _SPRulerClass { GtkWidgetClass parent_class; - - void (* draw_ticks) (SPRuler *ruler, - cairo_t *cr); - void (* draw_pos) (SPRuler *ruler, - cairo_t *cr); }; -struct _SPRulerMetric -{ - gchar const *metric_name; - gchar const *abbrev; - /* This should be points_per_unit. This is the size of the unit - * in 1/72nd's of an inch and has nothing to do with screen pixels */ - gdouble pixels_per_unit; - gdouble ruler_scale[10]; - gint subdivide[5]; /* five possible modes of subdivision */ -}; +GType sp_ruler_get_type (void) G_GNUC_CONST; + +GtkWidget* sp_ruler_new (GtkOrientation orientation); + +void sp_ruler_add_track_widget (SPRuler *ruler, + GtkWidget *widget); +void sp_ruler_remove_track_widget (SPRuler *ruler, + GtkWidget *widget); + +void sp_ruler_set_unit (SPRuler *ruler, + SPMetric unit); +SPMetric sp_ruler_get_unit (SPRuler *ruler); +void sp_ruler_set_position (SPRuler *ruler, + gdouble set_position); +gdouble sp_ruler_get_position (SPRuler *ruler); +void sp_ruler_set_range (SPRuler *ruler, + gdouble lower, + gdouble upper, + gdouble max_size); +void sp_ruler_get_range (SPRuler *ruler, + gdouble *lower, + gdouble *upper, + gdouble *max_size); -GType sp_ruler_get_type (void) G_GNUC_CONST; -GtkWidget* sp_ruler_new (GtkOrientation orientation); -void sp_ruler_set_range (SPRuler *ruler, - gdouble lower, - gdouble upper, - gdouble position, - gdouble max_size); -void sp_ruler_get_range (SPRuler *ruler, - gdouble *lower, - gdouble *upper, - gdouble *position, - gdouble *max_size); -void sp_ruler_set_metric(SPRuler *ruler, SPMetric metric); -SPMetric sp_ruler_get_metric(SPRuler *ruler); +G_END_DECLS #endif /* __SP_RULER_H__ */ diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index 4378bc19d..549581610 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -52,6 +52,7 @@ #include "ink-action.h" #include <2geom/rect.h> #include "ui/icon-names.h" +#include "select-toolbar.h" using Inkscape::UnitTracker; using Inkscape::DocumentUndo; @@ -87,13 +88,13 @@ sp_selection_layout_widget_update(SPWidget *spw, Inkscape::Selection *sel) if (unit.base == SP_UNIT_DIMENSIONLESS) { double const val = 1. / unit.unittobase; for (unsigned i = 0; i < G_N_ELEMENTS(keyval); ++i) { - GtkAdjustment *a = (GtkAdjustment *) g_object_get_data(G_OBJECT(spw), keyval[i].key); + GtkAdjustment *a = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(spw), keyval[i].key)); gtk_adjustment_set_value(a, val); tracker->setFullVal( a, keyval[i].val ); } } else { for (unsigned i = 0; i < G_N_ELEMENTS(keyval); ++i) { - GtkAdjustment *a = (GtkAdjustment *) g_object_get_data(G_OBJECT(spw), keyval[i].key); + GtkAdjustment *a = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(spw), keyval[i].key)); gtk_adjustment_set_value(a, sp_pixels_get_units(keyval[i].val, unit)); } } @@ -497,7 +498,7 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb // four spinbuttons eact = create_adjustment_action( "XAction", C_("Select toolbar", "X position"), C_("Select toolbar", "X:"), "X", - -1e6, GTK_WIDGET(desktop->canvas), tracker, spw, + -1e6, GTK_WIDGET(desktop->canvas), tracker, spw, _("Horizontal coordinate of selection"), TRUE ); gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); @@ -509,7 +510,7 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb contextActions->push_back( GTK_ACTION(eact) ); eact = create_adjustment_action( "WidthAction", C_("Select toolbar", "Width"), C_("Select toolbar", "W:"), "width", - 1e-3, GTK_WIDGET(desktop->canvas), tracker, spw, + 0.0, GTK_WIDGET(desktop->canvas), tracker, spw, _("Width of selection"), FALSE ); gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); @@ -528,7 +529,7 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb } eact = create_adjustment_action( "HeightAction", C_("Select toolbar", "Height"), C_("Select toolbar", "H:"), "height", - 1e-3, GTK_WIDGET(desktop->canvas), tracker, spw, + 0.0, GTK_WIDGET(desktop->canvas), tracker, spw, _("Height of selection"), FALSE ); gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); contextActions->push_back( GTK_ACTION(eact) ); diff --git a/src/widgets/shrink-wrap-button.cpp b/src/widgets/shrink-wrap-button.cpp index fc844f5ec..941a0466c 100644 --- a/src/widgets/shrink-wrap-button.cpp +++ b/src/widgets/shrink-wrap-button.cpp @@ -16,6 +16,8 @@ #include <gtkmm/button.h> #include <gtk/gtk.h> +#include "shrink-wrap-button.h" + namespace Inkscape { namespace Widgets { diff --git a/src/widgets/sp-attribute-widget.cpp b/src/widgets/sp-attribute-widget.cpp index a1702a864..1f0fcd94e 100644 --- a/src/widgets/sp-attribute-widget.cpp +++ b/src/widgets/sp-attribute-widget.cpp @@ -12,9 +12,18 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include "sp-attribute-widget.h" + #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> @@ -24,7 +33,6 @@ #include "document.h" #include "document-undo.h" #include "verbs.h" -#include "sp-attribute-widget.h" using Inkscape::DocumentUndo; @@ -150,11 +158,14 @@ void SPAttributeTable::set_object(SPObject *object, release_connection = object->connectRelease (sigc::bind<1>(sigc::ptr_fun(&sp_attribute_table_object_release), this)); // Create table - table = new Gtk::Table (attributes.size(), 2, false); +#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()); - } + gtk_container_add(GTK_CONTAINER(parent), (GtkWidget*)table->gobj()); // Fill rows _attributes = attributes; @@ -162,18 +173,41 @@ 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); + ee->set_margin_right(XPAD); + 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", G_CALLBACK (sp_attribute_table_entry_changed), diff --git a/src/widgets/sp-attribute-widget.h b/src/widgets/sp-attribute-widget.h index fb8a74632..d9b972201 100644 --- a/src/widgets/sp-attribute-widget.h +++ b/src/widgets/sp-attribute-widget.h @@ -15,13 +15,22 @@ #ifndef SEEN_DIALOGS_SP_ATTRIBUTE_WIDGET_H #define SEEN_DIALOGS_SP_ATTRIBUTE_WIDGET_H -#include <gtkmm/table.h> +#if HAVE_CONFIG_H +# include "config.h" +#endif + #include <gtkmm/widget.h> #include <stddef.h> #include <sigc++/connection.h> namespace Gtk { class Entry; + +#if WITH_GTKMM_3_0 +class Grid; +#else +class Table; +#endif } namespace Inkscape { @@ -126,12 +135,16 @@ public: bool blocked; 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. * * _attributes stores the attribute names of the selected object that diff --git a/src/widgets/sp-color-gtkselector.cpp b/src/widgets/sp-color-gtkselector.cpp deleted file mode 100644 index 2e00aca71..000000000 --- a/src/widgets/sp-color-gtkselector.cpp +++ /dev/null @@ -1,155 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include <glibmm/i18n.h> -#include "sp-color-gtkselector.h" - - -static void sp_color_gtkselector_class_init (SPColorGtkselectorClass *klass); -static void sp_color_gtkselector_init (SPColorGtkselector *csel); -static void sp_color_gtkselector_dispose(GObject *object); - -static void sp_color_gtkselector_show_all (GtkWidget *widget); -static void sp_color_gtkselector_hide(GtkWidget *widget); - - -static SPColorSelectorClass *parent_class; - -#define XPAD 4 -#define YPAD 1 - -GType -sp_color_gtkselector_get_type (void) -{ - static GType type = 0; - if (!type) { - static const GTypeInfo info = { - sizeof (SPColorGtkselectorClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) sp_color_gtkselector_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (SPColorGtkselector), - 0, /* n_preallocs */ - (GInstanceInitFunc) sp_color_gtkselector_init, - NULL, - }; - - type = g_type_register_static (SP_TYPE_COLOR_SELECTOR, - "SPColorGtkselector", - &info, - static_cast< GTypeFlags > (0) ); - } - return type; -} - -static void -sp_color_gtkselector_class_init (SPColorGtkselectorClass *klass) -{ - static const gchar* nameset[] = {N_("System"), 0}; - GObjectClass *object_class = (GObjectClass *) klass; - GtkWidgetClass *widget_class; - SPColorSelectorClass *selector_class; - - widget_class = (GtkWidgetClass *) klass; - selector_class = SP_COLOR_SELECTOR_CLASS (klass); - - parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass)); - - selector_class->name = nameset; - selector_class->submode_count = 1; - - object_class->dispose = sp_color_gtkselector_dispose; - - widget_class->show_all = sp_color_gtkselector_show_all; - widget_class->hide = sp_color_gtkselector_hide; -} - -void sp_color_gtkselector_init (SPColorGtkselector *csel) -{ - SP_COLOR_SELECTOR(csel)->base = new ColorGtkselector( SP_COLOR_SELECTOR(csel) ); - - if ( SP_COLOR_SELECTOR(csel)->base ) - { - SP_COLOR_SELECTOR(csel)->base->init(); - } -} - -void ColorGtkselector::init() -{ - GtkWidget *gtksel = gtk_color_selection_new(); - gtk_widget_show (gtksel); - _gtkThing = GTK_COLOR_SELECTION (gtksel); - gtk_box_pack_start (GTK_BOX (_csel), gtksel, TRUE, TRUE, 0); - - _sigId = g_signal_connect(gtksel, "color-changed", G_CALLBACK( _gtkChanged ), _csel); -} - -static void sp_color_gtkselector_dispose(GObject *object) -{ - if (((GObjectClass *) (parent_class))->dispose) - (* ((GObjectClass *) (parent_class))->dispose) (object); -} - -static void -sp_color_gtkselector_show_all (GtkWidget *widget) -{ - gtk_widget_show (widget); -} - -static void sp_color_gtkselector_hide(GtkWidget *widget) -{ - gtk_widget_hide(widget); -} - -GtkWidget * -sp_color_gtkselector_new( GType ) -{ - SPColorGtkselector *csel; - - csel = (SPColorGtkselector*)g_object_new (SP_TYPE_COLOR_GTKSELECTOR, NULL); - - return GTK_WIDGET (csel); -} - -ColorGtkselector::ColorGtkselector( SPColorSelector* csel ) - : ColorSelector( csel ), - _gtkThing(0) -{ -} - -ColorGtkselector::~ColorGtkselector() -{ -} - -void ColorGtkselector::_colorChanged() -{ - GdkColor gcolor; - - gcolor.pixel = 0; - gcolor.red = static_cast< guint16 >(_color.v.c[0] * 65535); - gcolor.green = static_cast< guint16 >(_color.v.c[1] * 65535); - gcolor.blue = static_cast< guint16 >(_color.v.c[2] * 65535); - -// g_message( "***** _colorChanged %04x %04x %04x", gcolor.red, gcolor.green, gcolor.blue ); - g_signal_handler_block( _gtkThing, _sigId ); - gtk_color_selection_set_current_alpha( _gtkThing, static_cast<guint16>(65535 * _alpha) ); - gtk_color_selection_set_current_color( _gtkThing, &gcolor ); - g_signal_handler_unblock(_gtkThing, _sigId ); -} - -void ColorGtkselector::_gtkChanged( GtkColorSelection *colorselection, SPColorGtkselector *gtksel ) -{ - GdkColor color; - gtk_color_selection_get_current_color (colorselection, &color); - - guint16 alpha = gtk_color_selection_get_current_alpha (colorselection); - - SPColor ourColor( (color.red / 65535.0), (color.green / 65535.0), (color.blue / 65535.0) ); - -// g_message( "***** _gtkChanged %04x %04x %04x", color.red, color.green, color.blue ); - - ColorGtkselector* gtkInst = static_cast<ColorGtkselector *>(SP_COLOR_SELECTOR(gtksel)->base); - gtkInst->_updateInternals( ourColor, static_cast< gfloat > (alpha) / 65535.0, gtk_color_selection_is_adjusting(colorselection) ); -} diff --git a/src/widgets/sp-color-gtkselector.h b/src/widgets/sp-color-gtkselector.h deleted file mode 100644 index 3142406c1..000000000 --- a/src/widgets/sp-color-gtkselector.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef SEEN_SP_COLOR_GTKSELECTOR_H -#define SEEN_SP_COLOR_GTKSELECTOR_H - -#include <gtk/gtk.h> -#include "../color.h" -#include "sp-color-selector.h" - -#include <glib.h> - - - -struct SPColorGtkselector; - - - -class ColorGtkselector: public ColorSelector -{ -public: - ColorGtkselector( SPColorSelector* csel ); - virtual ~ColorGtkselector(); - - virtual void init(); - -protected: - static void _gtkChanged( GtkColorSelection *colorselection, SPColorGtkselector *gtksel ); - - virtual void _colorChanged(); - - GtkColorSelection* _gtkThing; - gulong _sigId; -}; - - - -#define SP_TYPE_COLOR_GTKSELECTOR (sp_color_gtkselector_get_type ()) -#define SP_COLOR_GTKSELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_COLOR_GTKSELECTOR, SPColorGtkselector)) -#define SP_COLOR_GTKSELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_COLOR_GTKSELECTOR, SPColorGtkselectorClass)) -#define SP_IS_COLOR_GTKSELECTOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_COLOR_GTKSELECTOR)) -#define SP_IS_COLOR_GTKSELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SP_TYPE_COLOR_GTKSELECTOR)) - -struct SPColorGtkselector { - SPColorSelector base; -}; - -struct SPColorGtkselectorClass { - SPColorSelectorClass parent_class; -}; - -GType sp_color_gtkselector_get_type (void); - -GtkWidget *sp_color_gtkselector_new( GType selector_type ); - - - -#endif // SEEN_SP_COLOR_GTKSELECTOR_H diff --git a/src/widgets/sp-color-icc-selector.cpp b/src/widgets/sp-color-icc-selector.cpp index d04f17a30..ce9323311 100644 --- a/src/widgets/sp-color-icc-selector.cpp +++ b/src/widgets/sp-color-icc-selector.cpp @@ -1,6 +1,8 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif + +#include "gradient-vector.h" #include <math.h> #include <gtk/gtk.h> #include <glibmm/i18n.h> @@ -11,7 +13,6 @@ #include "document.h" #include "inkscape.h" #include "profile-manager.h" -#include "gradient-vector.h" #define noDEBUG_LCMS @@ -104,12 +105,9 @@ sp_color_icc_selector_get_type (void) static void sp_color_icc_selector_class_init(SPColorICCSelectorClass *klass) { static const gchar* nameset[] = {N_("CMS"), 0}; - GObjectClass *object_class = (GObjectClass *) klass; - GtkWidgetClass *widget_class; - SPColorSelectorClass *selector_class; - - widget_class = (GtkWidgetClass *) klass; - selector_class = SP_COLOR_SELECTOR_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS(klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass); parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass)); @@ -272,13 +270,17 @@ void getThings( Inkscape::ColorProfile *prof, gchar const**& namers, gchar const void ColorICCSelector::init() { - GtkWidget *t; gint row = 0; _updating = FALSE; _dragging = FALSE; - t = gtk_table_new (5, 3, FALSE); +#if GTK_CHECK_VERSION(3,0,0) + GtkWidget *t = gtk_grid_new(); +#else + GtkWidget *t = gtk_table_new(5, 3, FALSE); +#endif + gtk_widget_show (t); gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 4); @@ -299,7 +301,16 @@ void ColorICCSelector::init() gtk_widget_set_tooltip_text( _fixupBtn, _("Fix RGB fallback to match icc-color() value.") ); //gtk_misc_set_alignment( GTK_MISC (_fixupBtn), 1.0, 0.5 ); gtk_widget_show( _fixupBtn ); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_fixupBtn, XPAD); + gtk_widget_set_margin_right(_fixupBtn, XPAD); + gtk_widget_set_margin_top(_fixupBtn, YPAD); + gtk_widget_set_margin_bottom(_fixupBtn, YPAD); + gtk_grid_attach(GTK_GRID(t), _fixupBtn, 0, row, 1, 1); +#else gtk_table_attach( GTK_TABLE (t), _fixupBtn, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD ); +#endif // Combobox and store with 2 columns : label (0) and full name (1) GtkListStore *store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); @@ -315,7 +326,16 @@ void ColorICCSelector::init() gtk_widget_show( _profileSel ); gtk_combo_box_set_active( GTK_COMBO_BOX(_profileSel), 0 ); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_profileSel, XPAD); + gtk_widget_set_margin_right(_profileSel, XPAD); + gtk_widget_set_margin_top(_profileSel, YPAD); + gtk_widget_set_margin_bottom(_profileSel, YPAD); + gtk_grid_attach(GTK_GRID(t), _profileSel, 1, row, 1, 1); +#else gtk_table_attach( GTK_TABLE(t), _profileSel, 1, 2, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD ); +#endif #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) _profChangedID = g_signal_connect( G_OBJECT(_profileSel), "changed", G_CALLBACK(_profileSelected), (gpointer)this ); @@ -342,7 +362,16 @@ void ColorICCSelector::init() #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) gtk_misc_set_alignment( GTK_MISC (_fooLabel[i]), 1.0, 0.5 ); gtk_widget_show( _fooLabel[i] ); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_fooLabel[i], XPAD); + gtk_widget_set_margin_right(_fooLabel[i], XPAD); + gtk_widget_set_margin_top(_fooLabel[i], YPAD); + gtk_widget_set_margin_bottom(_fooLabel[i], YPAD); + gtk_grid_attach(GTK_GRID(t), _fooLabel[i], 0, row, 1, 1); +#else gtk_table_attach( GTK_TABLE (t), _fooLabel[i], 0, 1, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD ); +#endif /* Adjustment */ gdouble step = static_cast<gdouble>(_fooScales[i]) / 100.0; @@ -358,7 +387,17 @@ void ColorICCSelector::init() gtk_widget_set_tooltip_text( _fooSlider[i], "." ); #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) gtk_widget_show( _fooSlider[i] ); - gtk_table_attach( GTK_TABLE (t), _fooSlider[i], 1, 2, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)GTK_FILL, XPAD, YPAD ); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_fooSlider[i], XPAD); + gtk_widget_set_margin_right(_fooSlider[i], XPAD); + gtk_widget_set_margin_top(_fooSlider[i], YPAD); + gtk_widget_set_margin_bottom(_fooSlider[i], YPAD); + gtk_widget_set_hexpand(_fooSlider[i], TRUE); + gtk_grid_attach(GTK_GRID(t), _fooSlider[i], 1, row, 1, 1); +#else + gtk_table_attach( GTK_TABLE (t), _fooSlider[i], 1, 2, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, XPAD, YPAD ); +#endif _fooBtn[i] = gtk_spin_button_new( _fooAdj[i], step, digits ); #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) @@ -369,7 +408,18 @@ void ColorICCSelector::init() sp_dialog_defocus_on_enter( _fooBtn[i] ); gtk_label_set_mnemonic_widget( GTK_LABEL(_fooLabel[i]), _fooBtn[i] ); gtk_widget_show( _fooBtn[i] ); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_fooBtn[i], XPAD); + gtk_widget_set_margin_right(_fooBtn[i], XPAD); + gtk_widget_set_margin_top(_fooBtn[i], YPAD); + gtk_widget_set_margin_bottom(_fooBtn[i], YPAD); + gtk_widget_set_halign(_fooBtn[i], GTK_ALIGN_CENTER); + gtk_widget_set_valign(_fooBtn[i], GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(t), _fooBtn[i], 2, row, 1, 1); +#else gtk_table_attach( GTK_TABLE (t), _fooBtn[i], 2, 3, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD ); +#endif _fooMap[i] = g_new( guchar, 4 * 1024 ); memset( _fooMap[i], 0x0ff, 1024 * 4 ); @@ -389,16 +439,35 @@ void ColorICCSelector::init() _label = gtk_label_new_with_mnemonic (_("_A:")); gtk_misc_set_alignment (GTK_MISC (_label), 1.0, 0.5); gtk_widget_show (_label); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_label, XPAD); + gtk_widget_set_margin_right(_label, XPAD); + gtk_widget_set_margin_top(_label, YPAD); + gtk_widget_set_margin_bottom(_label, YPAD); + gtk_grid_attach(GTK_GRID(t), _label, 0, row, 1, 1); +#else gtk_table_attach (GTK_TABLE (t), _label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD); +#endif /* Adjustment */ - _adj = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 10.0, 10.0); + _adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 255.0, 1.0, 10.0, 10.0)); /* Slider */ _slider = sp_color_slider_new (_adj); gtk_widget_set_tooltip_text (_slider, _("Alpha (opacity)")); gtk_widget_show (_slider); - gtk_table_attach (GTK_TABLE (t), _slider, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)GTK_FILL, XPAD, YPAD); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_slider, XPAD); + gtk_widget_set_margin_right(_slider, XPAD); + gtk_widget_set_margin_top(_slider, YPAD); + gtk_widget_set_margin_bottom(_slider, YPAD); + gtk_widget_set_hexpand(_slider, TRUE); + gtk_grid_attach(GTK_GRID(t), _slider, 1, row, 1, 1); +#else + gtk_table_attach (GTK_TABLE (t), _slider, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, XPAD, YPAD); +#endif sp_color_slider_set_colors( SP_COLOR_SLIDER( _slider ), SP_RGBA32_F_COMPOSE( 1.0, 1.0, 1.0, 0.0 ), @@ -412,7 +481,18 @@ void ColorICCSelector::init() sp_dialog_defocus_on_enter (_sbtn); gtk_label_set_mnemonic_widget (GTK_LABEL(_label), _sbtn); gtk_widget_show (_sbtn); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_sbtn, XPAD); + gtk_widget_set_margin_right(_sbtn, XPAD); + gtk_widget_set_margin_top(_sbtn, YPAD); + gtk_widget_set_margin_bottom(_sbtn, YPAD); + gtk_widget_set_halign(_sbtn, GTK_ALIGN_CENTER); + gtk_widget_set_valign(_sbtn, GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(t), _sbtn, 2, row, 1, 1); +#else gtk_table_attach (GTK_TABLE (t), _sbtn, 2, 3, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD); +#endif /* Signals */ g_signal_connect (G_OBJECT (_adj), "value_changed", @@ -428,8 +508,8 @@ void ColorICCSelector::init() static void sp_color_icc_selector_dispose(GObject *object) { - if (((GObjectClass *) (parent_class))->dispose) - (* ((GObjectClass *) (parent_class))->dispose)(object); + if ((G_OBJECT_CLASS(parent_class))->dispose) + (* (G_OBJECT_CLASS(parent_class))->dispose)(object); } static void @@ -510,9 +590,9 @@ void ColorICCSelector::_switchToProfile( gchar const* name ) if ( trans ) { guint32 val = _color.toRGBA32(0); guchar pre[4] = { - SP_RGBA32_R_U(val), - SP_RGBA32_G_U(val), - SP_RGBA32_B_U(val), + static_cast<guchar>(SP_RGBA32_R_U(val)), + static_cast<guchar>(SP_RGBA32_G_U(val)), + static_cast<guchar>(SP_RGBA32_B_U(val)), 255}; #ifdef DEBUG_LCMS g_message("Shoving in [%02x] [%02x] [%02x]", pre[0], pre[1], pre[2]); @@ -590,7 +670,7 @@ void ColorICCSelector::_profilesChanged( std::string const & name ) g_signal_handler_block( G_OBJECT(_profileSel), _profChangedID ); - GtkListStore *store = (GtkListStore *)gtk_combo_box_get_model (combo); + GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(combo)); gtk_list_store_clear(store); GtkTreeIter iter; @@ -926,7 +1006,7 @@ void ColorICCSelector::_adjustmentChanged( GtkAdjustment *adjustment, SPColorICC void ColorICCSelector::_sliderGrabbed( SPColorSlider */*slider*/, SPColorICCSelector */*cs*/ ) { -// ColorICCSelector* iccSelector = (ColorICCSelector*)(SP_COLOR_SELECTOR(cs)->base); +// ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base); // if (!iccSelector->_dragging) { // iccSelector->_dragging = TRUE; // iccSelector->_grabbed(); @@ -936,7 +1016,7 @@ void ColorICCSelector::_sliderGrabbed( SPColorSlider */*slider*/, SPColorICCSele void ColorICCSelector::_sliderReleased( SPColorSlider */*slider*/, SPColorICCSelector */*cs*/ ) { -// ColorICCSelector* iccSelector = (ColorICCSelector*)(SP_COLOR_SELECTOR(cs)->base); +// ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base); // if (iccSelector->_dragging) { // iccSelector->_dragging = FALSE; // iccSelector->_released(); @@ -953,7 +1033,7 @@ void ColorICCSelector::_sliderChanged( SPColorSlider */*slider*/, SPColorICCSele #ifdef DEBUG_LCMS g_message("Changed %p and %p", slider, cs ); #endif // DEBUG_LCMS -// ColorICCSelector* iccSelector = (ColorICCSelector*)(SP_COLOR_SELECTOR(cs)->base); +// ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base); // iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ), iccSelector->_dragging ); } diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp index 5c3c46502..588221a7c 100644 --- a/src/widgets/sp-color-notebook.cpp +++ b/src/widgets/sp-color-notebook.cpp @@ -17,6 +17,7 @@ # include "config.h" #endif +#include "widgets/icon.h" #include <cstring> #include <string> #include <cstdlib> @@ -37,6 +38,8 @@ #include "../profile-manager.h" #include "color-profile.h" #include "cms-system.h" +#include "tools-switch.h" +#include "event-context.h" using Inkscape::CMSSystem; @@ -104,7 +107,7 @@ sp_color_notebook_switch_page(GtkNotebook *notebook, { if ( colorbook ) { - ColorNotebook* nb = (ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base); + ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); nb->switchPage( notebook, page, page_num ); // remember the page we switched to @@ -141,7 +144,7 @@ static gint sp_color_notebook_menu_handler( GtkWidget *widget, GdkEvent *event ) if (event->type == GDK_BUTTON_PRESS) { SPColorSelector* csel = SP_COLOR_SELECTOR(widget); - ((ColorNotebook*)(csel->base))->menuHandler( event ); + (dynamic_cast<ColorNotebook*>(csel->base))->menuHandler( event ); /* Tell calling code that we have handled this event; the buck * stops here. */ @@ -170,11 +173,11 @@ static void sp_color_notebook_menuitem_response (GtkMenuItem *menuitem, gpointer { if ( active ) { - ((ColorNotebook*)(SP_COLOR_SELECTOR(entry->backPointer)->base))->addPage(entry->type, entry->submode); + (dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(entry->backPointer)->base))->addPage(entry->type, entry->submode); } else { - ((ColorNotebook*)(SP_COLOR_SELECTOR(entry->backPointer)->base))->removePage(entry->type, entry->submode); + (dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(entry->backPointer)->base))->removePage(entry->type, entry->submode); } } } @@ -192,7 +195,6 @@ sp_color_notebook_init (SPColorNotebook *colorbook) void ColorNotebook::init() { - GtkWidget* table = 0; guint row = 0; guint i = 0; guint j = 0; @@ -276,22 +278,49 @@ void ColorNotebook::init() } } - table = gtk_table_new (2, 3, FALSE); +#if GTK_CHECK_VERSION(3,0,0) + GtkWidget* table = gtk_grid_new(); +#else + GtkWidget* table = gtk_table_new(2, 3, FALSE); +#endif + gtk_widget_show (table); gtk_box_pack_start (GTK_BOX (_csel), table, TRUE, TRUE, 0); sp_set_font_size_smaller (_buttonbox); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_buttonbox, XPAD); + gtk_widget_set_margin_right(_buttonbox, XPAD); + gtk_widget_set_margin_top(_buttonbox, YPAD); + gtk_widget_set_margin_bottom(_buttonbox, YPAD); + gtk_widget_set_hexpand(_buttonbox, TRUE); + gtk_widget_set_valign(_buttonbox, GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(table), _buttonbox, 0, row, 2, 1); +#else gtk_table_attach (GTK_TABLE (table), _buttonbox, 0, 2, row, row + 1, static_cast<GtkAttachOptions>(GTK_EXPAND|GTK_FILL), - static_cast<GtkAttachOptions>(GTK_EXPAND|GTK_FILL), + static_cast<GtkAttachOptions>(0), XPAD, YPAD); +#endif + row++; +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_book, XPAD*2); + gtk_widget_set_margin_right(_book, XPAD*2); + gtk_widget_set_margin_top(_book, YPAD); + gtk_widget_set_margin_bottom(_book, YPAD); + gtk_widget_set_hexpand(_book, TRUE); + gtk_widget_set_vexpand(_book, TRUE); + gtk_grid_attach(GTK_GRID(table), _book, 0, row, 2, 1); +#else gtk_table_attach (GTK_TABLE (table), _book, 0, 2, row, row + 1, static_cast<GtkAttachOptions>(GTK_EXPAND|GTK_FILL), static_cast<GtkAttachOptions>(GTK_EXPAND|GTK_FILL), XPAD*2, YPAD); +#endif // restore the last active page Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -346,7 +375,6 @@ void ColorNotebook::init() #if GTK_CHECK_VERSION(3,0,0) GtkWidget *rgbabox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_set_homogeneous(GTK_BOX(rgbabox), FALSE); #else GtkWidget *rgbabox = gtk_hbox_new (FALSE, 0); #endif @@ -373,9 +401,19 @@ void ColorNotebook::init() gtk_widget_set_tooltip_text (_box_toomuchink, _("Too much ink!")); gtk_widget_set_sensitive (_box_toomuchink, false); gtk_box_pack_start(GTK_BOX(rgbabox), _box_toomuchink, FALSE, FALSE, 2); - #endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + + /* Color picker */ + GtkWidget *picker = gtk_image_new_from_icon_name ("color-picker", GTK_ICON_SIZE_SMALL_TOOLBAR); + _btn_picker = gtk_button_new (); + gtk_button_set_relief(GTK_BUTTON(_btn_picker), GTK_RELIEF_NONE); + gtk_widget_show (_btn); + gtk_container_add (GTK_CONTAINER (_btn_picker), picker); + gtk_widget_set_tooltip_text (_btn_picker, _("Pick colors from image")); + gtk_box_pack_start(GTK_BOX(rgbabox), _btn_picker, FALSE, FALSE, 2); + g_signal_connect(G_OBJECT(_btn_picker), "clicked", G_CALLBACK(ColorNotebook::_picker_clicked), _csel); + /* Create RGBA entry and color preview */ _rgbal = gtk_label_new_with_mnemonic (_("RGBA_:")); gtk_misc_set_alignment (GTK_MISC (_rgbal), 1.0, 0.5); @@ -397,7 +435,15 @@ void ColorNotebook::init() gtk_widget_hide(GTK_WIDGET(_box_toomuchink)); #endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(rgbabox, XPAD); + gtk_widget_set_margin_right(rgbabox, XPAD); + gtk_widget_set_margin_top(rgbabox, YPAD); + gtk_widget_set_margin_bottom(rgbabox, YPAD); + gtk_grid_attach(GTK_GRID(table), rgbabox, 0, row, 2, 1); +#else gtk_table_attach (GTK_TABLE (table), rgbabox, 0, 2, row, row + 1, GTK_FILL, GTK_SHRINK, XPAD, YPAD); +#endif #ifdef SPCS_PREVIEW _p = sp_color_preview_new (0xffffffff); @@ -453,14 +499,11 @@ static void sp_color_notebook_hide(GtkWidget *widget) gtk_widget_hide(widget); } -GtkWidget * -sp_color_notebook_new (void) +GtkWidget *sp_color_notebook_new() { - SPColorNotebook *colorbook; - - colorbook = (SPColorNotebook*)g_object_new (SP_TYPE_COLOR_NOTEBOOK, NULL); + SPColorNotebook *colorbook = SP_COLOR_NOTEBOOK(g_object_new (SP_TYPE_COLOR_NOTEBOOK, NULL)); - return GTK_WIDGET (colorbook); + return GTK_WIDGET(colorbook); } ColorNotebook::ColorNotebook( SPColorSelector* csel ) @@ -496,9 +539,17 @@ void ColorNotebook::_colorChanged() _updateRgbaEntry( _color, _alpha ); } +void ColorNotebook::_picker_clicked(GtkWidget * /*widget*/, SPColorNotebook * /*colorbook*/) +{ + // Set the dropper into a "one click" mode, so it reverts to the previous tool after a click + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/tools/dropper/onetimepick", true); + sp_toggle_dropper(SP_ACTIVE_DESKTOP); +} + void ColorNotebook::_rgbaEntryChangedHook(GtkEntry *entry, SPColorNotebook *colorbook) { - ((ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base))->_rgbaEntryChanged( entry ); + (dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base))->_rgbaEntryChanged( entry ); } void ColorNotebook::_rgbaEntryChanged(GtkEntry* entry) @@ -608,7 +659,7 @@ void ColorNotebook::_setCurrentPage(int i) void ColorNotebook::_buttonClicked(GtkWidget *widget, SPColorNotebook *colorbook) { - ColorNotebook* nb = (ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base); + ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget))) { return; @@ -623,14 +674,14 @@ void ColorNotebook::_buttonClicked(GtkWidget *widget, SPColorNotebook *colorboo void ColorNotebook::_entryGrabbed (SPColorSelector *, SPColorNotebook *colorbook) { - ColorNotebook* nb = (ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base); + ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); nb->_grabbed(); } void ColorNotebook::_entryDragged (SPColorSelector *csel, SPColorNotebook *colorbook) { gboolean oldState; - ColorNotebook* nb = (ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base); + ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); oldState = nb->_dragging; @@ -642,14 +693,14 @@ void ColorNotebook::_entryDragged (SPColorSelector *csel, SPColorNotebook *color void ColorNotebook::_entryReleased (SPColorSelector *, SPColorNotebook *colorbook) { - ColorNotebook* nb = (ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base); + ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); nb->_released(); } void ColorNotebook::_entryChanged (SPColorSelector *csel, SPColorNotebook *colorbook) { gboolean oldState; - ColorNotebook* nb = (ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base); + ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); oldState = nb->_dragging; @@ -666,7 +717,7 @@ void ColorNotebook::_entryModified (SPColorSelector *csel, SPColorNotebook *colo g_return_if_fail (csel != NULL); g_return_if_fail (SP_IS_COLOR_SELECTOR (csel)); - ColorNotebook* nb = (ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base); + ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); SPColor color; gfloat alpha = 1.0; diff --git a/src/widgets/sp-color-notebook.h b/src/widgets/sp-color-notebook.h index 7532e1a6f..6e5111132 100644 --- a/src/widgets/sp-color-notebook.h +++ b/src/widgets/sp-color-notebook.h @@ -47,6 +47,7 @@ protected: static void _entryChanged( SPColorSelector *csel, SPColorNotebook *colorbook ); static void _entryModified( SPColorSelector *csel, SPColorNotebook *colorbook ); static void _buttonClicked(GtkWidget *widget, SPColorNotebook *colorbook); + static void _picker_clicked(GtkWidget *widget, SPColorNotebook *colorbook); virtual void _colorChanged(); @@ -66,6 +67,7 @@ protected: #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) GtkWidget *_box_outofgamut, *_box_colormanaged, *_box_toomuchink; #endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + GtkWidget *_btn_picker; GtkWidget *_p; /* Color preview */ GtkWidget *_btn; GtkWidget *_popup; diff --git a/src/widgets/sp-color-scales.cpp b/src/widgets/sp-color-scales.cpp index 1af5a1068..c3f9d511c 100644 --- a/src/widgets/sp-color-scales.cpp +++ b/src/widgets/sp-color-scales.cpp @@ -78,12 +78,9 @@ static void sp_color_scales_class_init (SPColorScalesClass *klass) { static const gchar* nameset[] = {N_("RGB"), N_("HSL"), N_("CMYK"), 0}; - GObjectClass *object_class = (GObjectClass *) klass; - GtkWidgetClass *widget_class; - SPColorSelectorClass *selector_class; - - widget_class = (GtkWidgetClass *) klass; - selector_class = SP_COLOR_SELECTOR_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS(klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass); parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass)); @@ -133,13 +130,16 @@ void sp_color_scales_init (SPColorScales *cs) void ColorScales::init() { - GtkWidget *t; gint i; _updating = FALSE; _dragging = FALSE; - t = gtk_table_new (5, 3, FALSE); +#if GTK_CHECK_VERSION(3,0,0) + GtkWidget *t = gtk_grid_new(); +#else + GtkWidget *t = gtk_table_new (5, 3, FALSE); +#endif gtk_widget_show (t); gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 4); @@ -149,20 +149,51 @@ void ColorScales::init() _l[i] = gtk_label_new(""); gtk_misc_set_alignment (GTK_MISC (_l[i]), 1.0, 0.5); gtk_widget_show (_l[i]); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_l[i], XPAD); + gtk_widget_set_margin_right(_l[i], XPAD); + gtk_widget_set_margin_top(_l[i], YPAD); + gtk_widget_set_margin_bottom(_l[i], YPAD); + gtk_grid_attach(GTK_GRID(t), _l[i], 0, i, 1, 1); +#else gtk_table_attach (GTK_TABLE (t), _l[i], 0, 1, i, i + 1, GTK_FILL, GTK_FILL, XPAD, YPAD); +#endif + /* Adjustment */ - _a[i] = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, _rangeLimit, 1.0, 10.0, 10.0); + _a[i] = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, _rangeLimit, 1.0, 10.0, 10.0)); /* Slider */ _s[i] = sp_color_slider_new (_a[i]); gtk_widget_show (_s[i]); - gtk_table_attach (GTK_TABLE (t), _s[i], 1, 2, i, i + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)GTK_FILL, XPAD, YPAD); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_s[i], XPAD); + gtk_widget_set_margin_right(_s[i], XPAD); + gtk_widget_set_margin_top(_s[i], YPAD); + gtk_widget_set_margin_bottom(_s[i], YPAD); + gtk_widget_set_hexpand(_s[i], TRUE); + gtk_grid_attach(GTK_GRID(t), _s[i], 1, i, 1, 1); +#else + gtk_table_attach (GTK_TABLE (t), _s[i], 1, 2, i, i + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, XPAD, YPAD); +#endif /* Spinbutton */ _b[i] = gtk_spin_button_new (GTK_ADJUSTMENT (_a[i]), 1.0, 0); sp_dialog_defocus_on_enter (_b[i]); gtk_label_set_mnemonic_widget (GTK_LABEL(_l[i]), _b[i]); gtk_widget_show (_b[i]); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_b[i], XPAD); + gtk_widget_set_margin_right(_b[i], XPAD); + gtk_widget_set_margin_top(_b[i], YPAD); + gtk_widget_set_margin_bottom(_b[i], YPAD); + gtk_widget_set_halign(_b[i], GTK_ALIGN_CENTER); + gtk_widget_set_valign(_b[i], GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(t), _b[i], 2, i, 1, 1); +#else gtk_table_attach (GTK_TABLE (t), _b[i], 2, 3, i, i + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD); +#endif /* Attach channel value to adjustment */ g_object_set_data (G_OBJECT (_a[i]), "channel", GINT_TO_POINTER (i)); @@ -183,8 +214,8 @@ void ColorScales::init() static void sp_color_scales_dispose(GObject *object) { - if (((GObjectClass *) (parent_class))->dispose) - (* ((GObjectClass *) (parent_class))->dispose) (object); + if ((G_OBJECT_CLASS(parent_class))->dispose) + (* (G_OBJECT_CLASS(parent_class))->dispose) (object); } static void @@ -198,12 +229,9 @@ static void sp_color_scales_hide(GtkWidget *widget) gtk_widget_hide(widget); } -GtkWidget * -sp_color_scales_new (void) +GtkWidget *sp_color_scales_new() { - SPColorScales *csel; - - csel = (SPColorScales*)g_object_new (SP_TYPE_COLOR_SCALES, NULL); + SPColorScales *csel = SP_COLOR_SCALES(g_object_new (SP_TYPE_COLOR_SCALES, NULL)); return GTK_WIDGET (csel); } @@ -435,7 +463,7 @@ void ColorScales::setMode(SPColorScalesMode mode) gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_A:")); gtk_widget_set_tooltip_text (_s[3], _("Alpha (opacity)")); gtk_widget_set_tooltip_text (_b[3], _("Alpha (opacity)")); - sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), (guchar*)sp_color_scales_hue_map ()); + sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), (guchar *)(sp_color_scales_hue_map())); gtk_widget_hide (_l[4]); gtk_widget_hide (_s[4]); gtk_widget_hide (_b[4]); diff --git a/src/widgets/sp-color-slider.cpp b/src/widgets/sp-color-slider.cpp index d58d495bb..471ee3852 100644 --- a/src/widgets/sp-color-slider.cpp +++ b/src/widgets/sp-color-slider.cpp @@ -86,12 +86,10 @@ sp_color_slider_get_type (void) static void sp_color_slider_class_init(SPColorSliderClass *klass) { - GObjectClass *object_class = (GObjectClass *) klass; - GtkWidgetClass *widget_class; + GObjectClass *object_class = G_OBJECT_CLASS(klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); - widget_class = (GtkWidgetClass *) klass; - - parent_class = (GtkWidgetClass*)g_type_class_peek_parent (klass); + parent_class = GTK_WIDGET_CLASS(g_type_class_peek_parent(klass)); slider_signals[GRABBED] = g_signal_new ("grabbed", G_TYPE_FROM_CLASS(object_class), @@ -185,8 +183,8 @@ static void sp_color_slider_dispose(GObject *object) slider->adjustment = NULL; } - if (((GObjectClass *) (parent_class))->dispose) - (* ((GObjectClass *) (parent_class))->dispose) (object); + if ((G_OBJECT_CLASS(parent_class))->dispose) + (* (G_OBJECT_CLASS(parent_class))->dispose) (object); } static void @@ -311,17 +309,16 @@ sp_color_slider_button_press (GtkWidget *widget, GdkEventButton *event) g_signal_emit (G_OBJECT (slider), slider_signals[DRAGGED], 0); #if GTK_CHECK_VERSION(3,0,0) - gdk_device_grab(gdk_event_get_device((GdkEvent*)event), + gdk_device_grab(gdk_event_get_device(reinterpret_cast<GdkEvent *>(event)), gtk_widget_get_window(widget), GDK_OWNERSHIP_NONE, FALSE, - (GdkEventMask)(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), + static_cast<GdkEventMask>(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), NULL, event->time); #else gdk_pointer_grab(gtk_widget_get_window(widget), FALSE, - (GdkEventMask)(GDK_POINTER_MOTION_MASK | - GDK_BUTTON_RELEASE_MASK), + static_cast<GdkEventMask>(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), NULL, NULL, event->time); #endif } @@ -339,8 +336,8 @@ sp_color_slider_button_release (GtkWidget *widget, GdkEventButton *event) if (event->button == 1) { #if GTK_CHECK_VERSION(3,0,0) - gdk_device_ungrab(gdk_event_get_device((GdkEvent *)event), - gdk_event_get_time((GdkEvent *)event)); + gdk_device_ungrab(gdk_event_get_device(reinterpret_cast<GdkEvent *>(event)), + gdk_event_get_time(reinterpret_cast<GdkEvent *>(event))); #else gdk_pointer_ungrab (event->time); #endif @@ -373,12 +370,9 @@ sp_color_slider_motion_notify (GtkWidget *widget, GdkEventMotion *event) return FALSE; } -GtkWidget * -sp_color_slider_new (GtkAdjustment *adjustment) +GtkWidget *sp_color_slider_new(GtkAdjustment *adjustment) { - SPColorSlider *slider; - - slider = (SPColorSlider*)g_object_new (SP_TYPE_COLOR_SLIDER, NULL); + SPColorSlider *slider = SP_COLOR_SLIDER(g_object_new(SP_TYPE_COLOR_SLIDER, NULL)); sp_color_slider_set_adjustment (slider, adjustment); @@ -391,7 +385,7 @@ void sp_color_slider_set_adjustment(SPColorSlider *slider, GtkAdjustment *adjust g_return_if_fail (SP_IS_COLOR_SLIDER (slider)); if (!adjustment) { - adjustment = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 1.0, 0.01, 0.0, 0.0); + adjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 1.0, 0.01, 0.0, 0.0)); } else { gtk_adjustment_set_page_increment(adjustment, 0.0); gtk_adjustment_set_page_size(adjustment, 0.0); @@ -451,7 +445,7 @@ sp_color_slider_set_map (SPColorSlider *slider, const guchar *map) g_return_if_fail (slider != NULL); g_return_if_fail (SP_IS_COLOR_SLIDER (slider)); - slider->map = (guchar *) map; + slider->map = const_cast<guchar *>(map); gtk_widget_queue_draw (GTK_WIDGET (slider)); } @@ -648,36 +642,26 @@ static gboolean sp_color_slider_draw(GtkWidget *widget, cairo_t *cr) gint x = (int)(slider->value * (carea.width - 1) - ARROW_SIZE / 2 + carea.x); gint y1 = carea.y; gint y2 = carea.y + carea.height - 1; - gint w = ARROW_SIZE; cairo_set_line_width(cr, 1.0); - GdkColor white, black; - gdk_color_parse("#fff", &white); - gdk_color_parse("#000", &black); - - while ( w > 0 ) - { - gdk_cairo_set_source_color(cr, &white); - cairo_move_to(cr, x - 0.5, y1 + 0.5); - cairo_line_to(cr, x + w - 1 + 0.5, y1 + 0.5); - cairo_move_to(cr, x - 0.5, y2 + 0.5); - cairo_line_to(cr, x + w - 1 + 0.5, y2 + 0.5); - cairo_stroke(cr); - w -=2; - x++; - if ( w > 0 ) - { - gdk_cairo_set_source_color(cr, &black); - cairo_move_to(cr, x - 0.5, y1 + 0.5); - cairo_line_to(cr, x + w - 1 + 0.5, y1 + 0.5); - cairo_move_to(cr, x - 0.5, y2 + 0.5); - cairo_line_to(cr, x + w - 1 + 0.5, y2 + 0.5); - cairo_stroke(cr); - } - y1++; - y2--; - } - + // Define top arrow + cairo_move_to(cr, x - 0.5, y1 + 0.5); + cairo_line_to(cr, x + ARROW_SIZE - 0.5, y1 + 0.5); + cairo_line_to(cr, x + (ARROW_SIZE-1)/2.0, y1 + ARROW_SIZE/2.0 + 0.5); + cairo_line_to(cr, x - 0.5, y1 + 0.5); + + // Define bottom arrow + cairo_move_to(cr, x - 0.5, y2 + 0.5); + cairo_line_to(cr, x + ARROW_SIZE - 0.5, y2 + 0.5); + cairo_line_to(cr, x + (ARROW_SIZE-1)/2.0, y2 - ARROW_SIZE/2.0 + 0.5); + cairo_line_to(cr, x - 0.5, y2 + 0.5); + + // Render both arrows + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_stroke_preserve(cr); + cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); + cairo_fill(cr); + return FALSE; } diff --git a/src/widgets/sp-color-wheel-selector.cpp b/src/widgets/sp-color-wheel-selector.cpp index 4cc9f9e4a..7c8bb1df7 100644 --- a/src/widgets/sp-color-wheel-selector.cpp +++ b/src/widgets/sp-color-wheel-selector.cpp @@ -9,6 +9,7 @@ #include "sp-color-scales.h" #include "sp-color-icc-selector.h" #include "../svg/svg-icc-color.h" +#include "ui/widget/gimpcolorwheel.h" G_BEGIN_DECLS @@ -56,12 +57,9 @@ sp_color_wheel_selector_get_type (void) static void sp_color_wheel_selector_class_init(SPColorWheelSelectorClass *klass) { static const gchar* nameset[] = {N_("Wheel"), 0}; - GObjectClass *object_class = (GObjectClass *) klass; - GtkWidgetClass *widget_class; - SPColorSelectorClass *selector_class; - - widget_class = (GtkWidgetClass *) klass; - selector_class = SP_COLOR_SELECTOR_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS(klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass); parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass)); @@ -104,64 +102,37 @@ void sp_color_wheel_selector_init (SPColorWheelSelector *cs) } } -static void resizeHSVWheel( GtkHSV *hsv, GtkAllocation *allocation ) -{ - gint diam = std::min(allocation->width, allocation->height); - - // drop a little for resizing - diam -= 4; - - GtkStyle *style = gtk_widget_get_style( GTK_WIDGET(hsv) ); - if ( style ) { - gint thick = std::max(style->xthickness, style->ythickness); - if (thick > 0) { - diam -= thick * 2; - } - } - gint padding = -1; - gtk_widget_style_get( GTK_WIDGET(hsv), - "focus-padding", &padding, - NULL ); - if (padding > 0) { - diam -= padding * 2; - } - - diam = std::max(20, diam); - gint ring = static_cast<gint>( static_cast<gdouble>(diam) / (4.0 * 1.618) ); - gtk_hsv_set_metrics( hsv, diam, ring ); -} - -static void handleWheelStyleSet(GtkHSV *hsv, GtkStyle* /*previous*/, gpointer /*userData*/) -{ - GtkAllocation allocation = {0, 0, 0, 0}; - gtk_widget_get_allocation( GTK_WIDGET(hsv), &allocation ); - resizeHSVWheel( hsv, &allocation ); -} - -static void handleWheelAllocation(GtkHSV *hsv, GtkAllocation *allocation, gpointer /*userData*/) -{ - resizeHSVWheel( hsv, allocation ); -} - void ColorWheelSelector::init() { - GtkWidget *t; gint row = 0; _updating = FALSE; _dragging = FALSE; - t = gtk_table_new (5, 3, FALSE); +#if GTK_CHECK_VERSION(3,0,0) + GtkWidget *t = gtk_grid_new(); +#else + GtkWidget *t = gtk_table_new (5, 3, FALSE); +#endif + gtk_widget_show (t); gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 0); /* Create components */ row = 0; - _wheel = gtk_hsv_new(); - gtk_hsv_set_metrics( GTK_HSV(_wheel), 48, 8 ); + _wheel = gimp_color_wheel_new(); gtk_widget_show( _wheel ); - gtk_table_attach( GTK_TABLE(t), _wheel, 0, 3, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), XPAD, YPAD); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(_wheel, GTK_ALIGN_FILL); + gtk_widget_set_valign(_wheel, GTK_ALIGN_FILL); + gtk_widget_set_hexpand(_wheel, TRUE); + gtk_widget_set_vexpand(_wheel, TRUE); + gtk_grid_attach(GTK_GRID(t), _wheel, 0, row, 3, 1); +#else + gtk_table_attach(GTK_TABLE(t), _wheel, 0, 3, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0); +#endif row++; @@ -169,16 +140,39 @@ void ColorWheelSelector::init() _label = gtk_label_new_with_mnemonic (_("_A:")); gtk_misc_set_alignment (GTK_MISC (_label), 1.0, 0.5); gtk_widget_show (_label); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_label, XPAD); + gtk_widget_set_margin_right(_label, XPAD); + gtk_widget_set_margin_top(_label, YPAD); + gtk_widget_set_margin_bottom(_label, YPAD); + gtk_widget_set_halign(_label, GTK_ALIGN_FILL); + gtk_widget_set_valign(_label, GTK_ALIGN_FILL); + gtk_grid_attach(GTK_GRID(t), _label, 0, row, 1, 1); +#else gtk_table_attach (GTK_TABLE (t), _label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD); +#endif /* Adjustment */ - _adj = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 10.0, 10.0); + _adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 255.0, 1.0, 10.0, 10.0)); /* Slider */ _slider = sp_color_slider_new (_adj); gtk_widget_set_tooltip_text (_slider, _("Alpha (opacity)")); gtk_widget_show (_slider); - gtk_table_attach (GTK_TABLE (t), _slider, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)GTK_FILL, XPAD, YPAD); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_slider, XPAD); + gtk_widget_set_margin_right(_slider, XPAD); + gtk_widget_set_margin_top(_slider, YPAD); + gtk_widget_set_margin_bottom(_slider, YPAD); + gtk_widget_set_hexpand(_slider, TRUE); + gtk_widget_set_halign(_slider, GTK_ALIGN_FILL); + gtk_widget_set_valign(_slider, GTK_ALIGN_FILL); + gtk_grid_attach(GTK_GRID(t), _slider, 1, row, 1, 1); +#else + gtk_table_attach(GTK_TABLE (t), _slider, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, XPAD, YPAD); +#endif sp_color_slider_set_colors (SP_COLOR_SLIDER (_slider), SP_RGBA32_F_COMPOSE (1.0, 1.0, 1.0, 0.0), @@ -192,7 +186,18 @@ void ColorWheelSelector::init() sp_dialog_defocus_on_enter (_sbtn); gtk_label_set_mnemonic_widget (GTK_LABEL(_label), _sbtn); gtk_widget_show (_sbtn); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(_sbtn, XPAD); + gtk_widget_set_margin_right(_sbtn, XPAD); + gtk_widget_set_margin_top(_sbtn, YPAD); + gtk_widget_set_margin_bottom(_sbtn, YPAD); + gtk_widget_set_halign(_sbtn, GTK_ALIGN_CENTER); + gtk_widget_set_valign(_sbtn, GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(t), _sbtn, 2, row, 1, 1); +#else gtk_table_attach (GTK_TABLE (t), _sbtn, 2, 3, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD); +#endif /* Signals */ g_signal_connect (G_OBJECT (_adj), "value_changed", @@ -207,19 +212,12 @@ void ColorWheelSelector::init() g_signal_connect( G_OBJECT(_wheel), "changed", G_CALLBACK (_wheelChanged), _csel ); - - - // GTK does not automatically scale the color wheel, so we have to add that in: - g_signal_connect( G_OBJECT (_wheel), "size-allocate", - G_CALLBACK (handleWheelAllocation), _csel ); - g_signal_connect( G_OBJECT (_wheel), "style-set", - G_CALLBACK (handleWheelStyleSet), _csel ); } static void sp_color_wheel_selector_dispose(GObject *object) { - if (((GObjectClass *) (parent_class))->dispose) - (* ((GObjectClass *) (parent_class))->dispose) (object); + if ((G_OBJECT_CLASS(parent_class))->dispose) + (* (G_OBJECT_CLASS(parent_class))->dispose) (object); } static void @@ -233,12 +231,9 @@ static void sp_color_wheel_selector_hide(GtkWidget *widget) gtk_widget_hide(widget); } -GtkWidget * -sp_color_wheel_selector_new (void) +GtkWidget *sp_color_wheel_selector_new() { - SPColorWheelSelector *csel; - - csel = (SPColorWheelSelector*)g_object_new (SP_TYPE_COLOR_WHEEL_SELECTOR, NULL); + SPColorWheelSelector *csel = SP_COLOR_WHEEL_SELECTOR(g_object_new (SP_TYPE_COLOR_WHEEL_SELECTOR, NULL)); return GTK_WIDGET (csel); } @@ -257,11 +252,9 @@ void ColorWheelSelector::_colorChanged() #endif _updating = TRUE; { - gdouble h = 0; - gdouble s = 0; - gdouble v = 0; - gtk_rgb_to_hsv( _color.v.c[0], _color.v.c[1], _color.v.c[2], &h, &s, &v ); - gtk_hsv_set_color( GTK_HSV(_wheel), h, s, v ); + float hsv[3] = {0,0,0}; + sp_color_rgb_to_hsv_floatv(hsv, _color.v.c[0], _color.v.c[1], _color.v.c[2]); + gimp_color_wheel_set_color( GIMP_COLOR_WHEEL(_wheel), hsv[0], hsv[1], hsv[2] ); } guint32 start = _color.toRGBA32( 0x00 ); @@ -332,21 +325,19 @@ void ColorWheelSelector::_sliderChanged( SPColorSlider *slider, SPColorWheelSele wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging ); } -void ColorWheelSelector::_wheelChanged( GtkHSV *hsv, SPColorWheelSelector *cs ) +void ColorWheelSelector::_wheelChanged( GimpColorWheel *wheel, SPColorWheelSelector *cs ) { ColorWheelSelector* wheelSelector = static_cast<ColorWheelSelector*>(SP_COLOR_SELECTOR(cs)->base); gdouble h = 0; gdouble s = 0; gdouble v = 0; - gtk_hsv_get_color( hsv, &h, &s, &v ); + gimp_color_wheel_get_color( wheel, &h, &s, &v ); - gdouble r = 0; - gdouble g = 0; - gdouble b = 0; - gtk_hsv_to_rgb(h, s, v, &r, &g, &b); + float rgb[3] = {0,0,0}; + sp_color_hsv_to_rgb_floatv (rgb, h, s, v); - SPColor color(r, g, b); + SPColor color(rgb[0], rgb[1], rgb[2]); guint32 start = color.toRGBA32( 0x00 ); guint32 mid = color.toRGBA32( 0x7f ); @@ -355,7 +346,7 @@ void ColorWheelSelector::_wheelChanged( GtkHSV *hsv, SPColorWheelSelector *cs ) sp_color_slider_set_colors (SP_COLOR_SLIDER(wheelSelector->_slider), start, mid, end); preserve_icc(&color, cs); - wheelSelector->_updateInternals( color, wheelSelector->_alpha, gtk_hsv_is_adjusting( hsv ) ); + wheelSelector->_updateInternals( color, wheelSelector->_alpha, gimp_color_wheel_is_adjusting(wheel) ); } diff --git a/src/widgets/sp-color-wheel-selector.h b/src/widgets/sp-color-wheel-selector.h index 4d8f79976..8e0dc6cea 100644 --- a/src/widgets/sp-color-wheel-selector.h +++ b/src/widgets/sp-color-wheel-selector.h @@ -10,7 +10,7 @@ -typedef struct _GtkHSV GtkHSV; +typedef struct _GimpColorWheel GimpColorWheel; struct SPColorWheelSelector; struct SPColorWheelSelectorClass; @@ -30,7 +30,7 @@ protected: static void _sliderGrabbed( SPColorSlider *slider, SPColorWheelSelector *cs ); static void _sliderReleased( SPColorSlider *slider, SPColorWheelSelector *cs ); static void _sliderChanged( SPColorSlider *slider, SPColorWheelSelector *cs ); - static void _wheelChanged( GtkHSV *hsv, SPColorWheelSelector *cs ); + static void _wheelChanged( GimpColorWheel *wheel, SPColorWheelSelector *cs ); static void _fooChanged( GtkWidget foo, SPColorWheelSelector *cs ); diff --git a/src/widgets/sp-widget.cpp b/src/widgets/sp-widget.cpp index 8d840da25..7876f0454 100644 --- a/src/widgets/sp-widget.cpp +++ b/src/widgets/sp-widget.cpp @@ -306,7 +306,7 @@ GtkWidget *SPWidgetImpl::constructGlobal(SPWidget *spw, Inkscape::Application *i g_signal_emit(spw, signals[CONSTRUCT], 0); - return (GtkWidget *) spw; + return GTK_WIDGET(spw); } void SPWidgetImpl::modifySelectionCB(Application *inkscape, Selection *selection, guint flags, SPWidget *spw) diff --git a/src/widgets/sp-widget.h b/src/widgets/sp-widget.h index d2177f486..3a23a92c5 100644 --- a/src/widgets/sp-widget.h +++ b/src/widgets/sp-widget.h @@ -27,7 +27,7 @@ namespace Inkscape { -class Application; +struct Application; class Selection; class SPWidgetImpl; diff --git a/src/widgets/sp-xmlview-attr-list.cpp b/src/widgets/sp-xmlview-attr-list.cpp index 8e7c94572..47b0ebb9d 100644 --- a/src/widgets/sp-xmlview-attr-list.cpp +++ b/src/widgets/sp-xmlview-attr-list.cpp @@ -41,12 +41,9 @@ static Inkscape::XML::NodeEventVector repr_events = { NULL /* order_changed */ }; -GtkWidget * -sp_xmlview_attr_list_new (Inkscape::XML::Node * repr) +GtkWidget *sp_xmlview_attr_list_new (Inkscape::XML::Node * repr) { - SPXMLViewAttrList * attr_list; - - attr_list = (SPXMLViewAttrList*)g_object_new (SP_TYPE_XMLVIEW_ATTR_LIST, NULL); + SPXMLViewAttrList * attr_list = SP_XMLVIEW_ATTR_LIST(g_object_new(SP_TYPE_XMLVIEW_ATTR_LIST, NULL)); attr_list->store = gtk_list_store_new (ATTR_N_COLS, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING ); gtk_tree_view_set_model (GTK_TREE_VIEW(attr_list), GTK_TREE_MODEL(attr_list->store)); @@ -71,7 +68,7 @@ sp_xmlview_attr_list_new (Inkscape::XML::Node * repr) sp_xmlview_attr_list_set_repr (attr_list, repr); - return (GtkWidget *) attr_list; + return GTK_WIDGET(attr_list); } void @@ -117,14 +114,14 @@ GType sp_xmlview_attr_list_get_type(void) void sp_xmlview_attr_list_class_init (SPXMLViewAttrListClass * klass) { #if GTK_CHECK_VERSION(3,0,0) - GtkWidgetClass * widget_class = (GtkWidgetClass *) klass; + GtkWidgetClass * widget_class = GTK_WIDGET_CLASS(klass); widget_class->destroy = sp_xmlview_attr_list_destroy; #else - GtkObjectClass * object_class = (GtkObjectClass *) klass; + GtkObjectClass * object_class = GTK_OBJECT_CLASS(klass); object_class->destroy = sp_xmlview_attr_list_destroy; #endif - parent_class = (GtkTreeViewClass*)g_type_class_peek_parent (klass); + parent_class = GTK_TREE_VIEW_CLASS(g_type_class_peek_parent (klass)); g_signal_new("row-value-changed", G_TYPE_FROM_CLASS(klass), diff --git a/src/widgets/sp-xmlview-content.cpp b/src/widgets/sp-xmlview-content.cpp index bf740baa0..ac64dabdb 100644 --- a/src/widgets/sp-xmlview-content.cpp +++ b/src/widgets/sp-xmlview-content.cpp @@ -46,14 +46,10 @@ static Inkscape::XML::NodeEventVector repr_events = { NULL /* order_changed */ }; -GtkWidget * -sp_xmlview_content_new (Inkscape::XML::Node * repr) +GtkWidget *sp_xmlview_content_new(Inkscape::XML::Node * repr) { - GtkTextBuffer *tb; - SPXMLViewContent *text; - - tb = gtk_text_buffer_new (NULL); - text = (SPXMLViewContent*)g_object_new (SP_TYPE_XMLVIEW_CONTENT, NULL); + GtkTextBuffer *tb = gtk_text_buffer_new(NULL); + SPXMLViewContent *text = SP_XMLVIEW_CONTENT(g_object_new(SP_TYPE_XMLVIEW_CONTENT, NULL)); gtk_text_view_set_buffer (GTK_TEXT_VIEW (text), tb); gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text), GTK_WRAP_CHAR); @@ -63,7 +59,7 @@ sp_xmlview_content_new (Inkscape::XML::Node * repr) sp_xmlview_content_set_repr (text, repr); - return (GtkWidget *) text; + return GTK_WIDGET(text); } void @@ -111,14 +107,14 @@ GType sp_xmlview_content_get_type(void) void sp_xmlview_content_class_init(SPXMLViewContentClass * klass) { #if GTK_CHECK_VERSION(3,0,0) - GtkWidgetClass * widget_class = (GtkWidgetClass *) klass; + GtkWidgetClass * widget_class = GTK_WIDGET_CLASS(klass); widget_class->destroy = sp_xmlview_content_destroy; #else - GtkObjectClass * object_class = (GtkObjectClass *) klass; + GtkObjectClass * object_class = GTK_OBJECT_CLASS(klass); object_class->destroy = sp_xmlview_content_destroy; #endif - parent_class = (GtkTextViewClass*)g_type_class_peek_parent (klass); + parent_class = GTK_TEXT_VIEW_CLASS(g_type_class_peek_parent (klass)); } void diff --git a/src/widgets/sp-xmlview-tree.cpp b/src/widgets/sp-xmlview-tree.cpp index 11e6717c1..43b7dc289 100644 --- a/src/widgets/sp-xmlview-tree.cpp +++ b/src/widgets/sp-xmlview-tree.cpp @@ -35,7 +35,6 @@ static void sp_xmlview_tree_destroy(GtkObject * object); #endif static NodeData * node_data_new (SPXMLViewTree * tree, GtkTreeIter * node, GtkTreeRowReference *rowref, Inkscape::XML::Node * repr); -static void node_data_free (gpointer data); static GtkTreeRowReference * add_node (SPXMLViewTree * tree, GtkTreeIter * parent, GtkTreeIter * before, Inkscape::XML::Node * repr); @@ -95,16 +94,13 @@ static const Inkscape::XML::NodeEventVector pi_repr_events = { static GtkTreeViewClass * parent_class = NULL; -GtkWidget * -sp_xmlview_tree_new (Inkscape::XML::Node * repr, void * /*factory*/, void * /*data*/) +GtkWidget *sp_xmlview_tree_new(Inkscape::XML::Node * repr, void * /*factory*/, void * /*data*/) { - SPXMLViewTree * tree; - - tree = (SPXMLViewTree*)g_object_new (SP_TYPE_XMLVIEW_TREE, NULL); + SPXMLViewTree *tree = SP_XMLVIEW_TREE(g_object_new (SP_TYPE_XMLVIEW_TREE, NULL)); - tree->store = gtk_tree_store_new (STORE_N_COLS, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER); + tree->store = gtk_tree_store_new (STORE_N_COLS, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER); - // Detach the model from the view until all the data is loaded + // Detach the model from the view until all the data is loaded g_object_ref(tree->store); gtk_tree_view_set_model(GTK_TREE_VIEW(tree), NULL); @@ -125,7 +121,7 @@ sp_xmlview_tree_new (Inkscape::XML::Node * repr, void * /*factory*/, void * /*da g_signal_connect(GTK_TREE_VIEW(tree), "drag_data_received", G_CALLBACK(on_drag_data_received), tree); g_signal_connect(GTK_TREE_VIEW(tree), "drag-motion", G_CALLBACK(do_drag_motion), tree); - return (GtkWidget *) tree; + return GTK_WIDGET(tree); } GType @@ -154,14 +150,14 @@ sp_xmlview_tree_get_type (void) void sp_xmlview_tree_class_init(SPXMLViewTreeClass * klass) { #if GTK_CHECK_VERSION(3,0,0) - GtkWidgetClass * widget_class = (GtkWidgetClass *) klass; + GtkWidgetClass * widget_class = GTK_WIDGET_CLASS(klass); widget_class->destroy = sp_xmlview_tree_destroy; #else - GtkObjectClass * object_class = (GtkObjectClass *) klass; + GtkObjectClass * object_class = GTK_OBJECT_CLASS(klass); object_class->destroy = sp_xmlview_tree_destroy; #endif - parent_class = (GtkTreeViewClass *) g_type_class_peek_parent (klass); + parent_class = GTK_TREE_VIEW_CLASS(g_type_class_peek_parent (klass)); // Signal for when a tree drag and drop has completed g_signal_new ( "tree_move", @@ -264,93 +260,71 @@ NodeData *node_data_new(SPXMLViewTree * tree, GtkTreeIter * /*node*/, GtkTreeRow return data; } -void -node_data_free (gpointer ptr) { - NodeData * data; - data = (NodeData *) ptr; - sp_repr_remove_listener_by_data (data->repr, data); - g_assert (data->repr != NULL); - Inkscape::GC::release(data->repr); - g_free (data); -} - -void -element_child_added (Inkscape::XML::Node * /*repr*/, Inkscape::XML::Node * child, Inkscape::XML::Node * ref, gpointer ptr) +void element_child_added (Inkscape::XML::Node * /*repr*/, Inkscape::XML::Node * child, Inkscape::XML::Node * ref, gpointer ptr) { - NodeData * data; - GtkTreeIter before; - - data = (NodeData *) ptr; + NodeData *data = static_cast<NodeData *>(ptr); + GtkTreeIter before; - if (data->tree->blocked) return; + if (data->tree->blocked) return; - if (!ref_to_sibling (data, ref, &before)) { - return; - } + if (!ref_to_sibling (data, ref, &before)) { + return; + } GtkTreeIter data_iter; tree_ref_to_iter(data->tree, &data_iter, data->rowref); - add_node (data->tree, &data_iter, &before, child); + add_node (data->tree, &data_iter, &before, child); } -void -element_attr_changed (Inkscape::XML::Node * repr, const gchar * key, const gchar * /*old_value*/, const gchar * new_value, bool /*is_interactive*/, gpointer ptr) +void element_attr_changed(Inkscape::XML::Node * repr, const gchar * key, const gchar * /*old_value*/, const gchar * new_value, bool /*is_interactive*/, gpointer ptr) { - NodeData * data; - gchar *label; - const gchar *layer; - - data = (NodeData *) ptr; + NodeData *data = static_cast<NodeData *>(ptr); + gchar *label; - if (data->tree->blocked) return; + if (data->tree->blocked) return; - if (0 != strcmp (key, "id") && 0 != strcmp (key, "inkscape:label")) - return; + if (0 != strcmp (key, "id") && 0 != strcmp (key, "inkscape:label")) + return; - new_value = repr->attribute("id"); - layer = repr->attribute("inkscape:label"); + new_value = repr->attribute("id"); + const gchar *layer = repr->attribute("inkscape:label"); - if (new_value && layer) { - label = g_strdup_printf ("<%s id=\"%s\" inkscape:label=\"%s\">", repr->name(), new_value, layer); - } else if (new_value) { - label = g_strdup_printf ("<%s id=\"%s\">", repr->name(), new_value); - } else { - label = g_strdup_printf ("<%s>", repr->name()); - } + if (new_value && layer) { + label = g_strdup_printf ("<%s id=\"%s\" inkscape:label=\"%s\">", repr->name(), new_value, layer); + } else if (new_value) { + label = g_strdup_printf ("<%s id=\"%s\">", repr->name(), new_value); + } else { + label = g_strdup_printf ("<%s>", repr->name()); + } - GtkTreeIter iter; - if (tree_ref_to_iter(data->tree, &iter, data->rowref)) { - gtk_tree_store_set (GTK_TREE_STORE(data->tree->store), &iter, STORE_TEXT_COL, label, -1); - } - g_free (label); + GtkTreeIter iter; + if (tree_ref_to_iter(data->tree, &iter, data->rowref)) { + gtk_tree_store_set (GTK_TREE_STORE(data->tree->store), &iter, STORE_TEXT_COL, label, -1); + } + g_free (label); } -void -element_child_removed (Inkscape::XML::Node * /*repr*/, Inkscape::XML::Node * child, Inkscape::XML::Node * /*ref*/, gpointer ptr) +void element_child_removed(Inkscape::XML::Node * /*repr*/, Inkscape::XML::Node * child, Inkscape::XML::Node * /*ref*/, gpointer ptr) { - NodeData * data; - data = (NodeData *) ptr; + NodeData *data = static_cast<NodeData *>(ptr); - if (data->tree->blocked) return; + if (data->tree->blocked) return; - GtkTreeIter iter; - if (repr_to_child (data, child, &iter)) { + GtkTreeIter iter; + if (repr_to_child (data, child, &iter)) { gtk_tree_store_remove (GTK_TREE_STORE(data->tree->store), &iter); } - } -void -element_order_changed (Inkscape::XML::Node * /*repr*/, Inkscape::XML::Node * child, Inkscape::XML::Node * /*oldref*/, Inkscape::XML::Node * newref, gpointer ptr) +void element_order_changed(Inkscape::XML::Node * /*repr*/, Inkscape::XML::Node * child, Inkscape::XML::Node * /*oldref*/, Inkscape::XML::Node * newref, gpointer ptr) { - NodeData * data; - GtkTreeIter before, node; - data = (NodeData *) ptr; + NodeData *data = static_cast<NodeData *>(ptr); + GtkTreeIter before, node; - if (data->tree->blocked) return; + if (data->tree->blocked) return; - ref_to_sibling (data, newref, &before); - repr_to_child (data, child, &node); + ref_to_sibling (data, newref, &before); + repr_to_child (data, child, &node); if (gtk_tree_store_iter_is_valid(data->tree->store, &before)) { gtk_tree_store_move_before (data->tree->store, &node, &before); @@ -360,59 +334,47 @@ element_order_changed (Inkscape::XML::Node * /*repr*/, Inkscape::XML::Node * chi } } -void -text_content_changed (Inkscape::XML::Node * /*repr*/, const gchar * /*old_content*/, const gchar * new_content, gpointer ptr) +void text_content_changed(Inkscape::XML::Node * /*repr*/, const gchar * /*old_content*/, const gchar * new_content, gpointer ptr) { - NodeData *data; - gchar *label; - - data = (NodeData *) ptr; + NodeData *data = static_cast<NodeData *>(ptr); - if (data->tree->blocked) return; + if (data->tree->blocked) return; - label = g_strdup_printf ("\"%s\"", new_content); + gchar *label = g_strdup_printf ("\"%s\"", new_content); GtkTreeIter iter; if (tree_ref_to_iter(data->tree, &iter, data->rowref)) { gtk_tree_store_set (GTK_TREE_STORE(data->tree->store), &iter, STORE_TEXT_COL, label, -1); } - g_free (label); + g_free (label); } -void -comment_content_changed (Inkscape::XML::Node */*repr*/, const gchar * /*old_content*/, const gchar *new_content, gpointer ptr) +void comment_content_changed(Inkscape::XML::Node * /*repr*/, const gchar * /*old_content*/, const gchar *new_content, gpointer ptr) { - NodeData *data; - gchar *label; - - data = (NodeData *) ptr; + NodeData *data = static_cast<NodeData*>(ptr); - if (data->tree->blocked) return; + if (data->tree->blocked) return; - label = g_strdup_printf ("<!--%s-->", new_content); + gchar *label = g_strdup_printf ("<!--%s-->", new_content); GtkTreeIter iter; if (tree_ref_to_iter(data->tree, &iter, data->rowref)) { gtk_tree_store_set (GTK_TREE_STORE(data->tree->store), &iter, STORE_TEXT_COL, label, -1); } - g_free (label); + g_free (label); } -void -pi_content_changed(Inkscape::XML::Node *repr, const gchar * /*old_content*/, const gchar *new_content, gpointer ptr) +void pi_content_changed(Inkscape::XML::Node *repr, const gchar * /*old_content*/, const gchar *new_content, gpointer ptr) { - NodeData *data; - gchar *label; - - data = (NodeData *) ptr; + NodeData *data = static_cast<NodeData *>(ptr); - if (data->tree->blocked) return; + if (data->tree->blocked) return; - label = g_strdup_printf ("<?%s %s?>", repr->name(), new_content); + gchar *label = g_strdup_printf ("<?%s %s?>", repr->name(), new_content); GtkTreeIter iter; if (tree_ref_to_iter(data->tree, &iter, data->rowref)) { gtk_tree_store_set (GTK_TREE_STORE(data->tree->store), &iter, STORE_TEXT_COL, label, -1); } - g_free (label); + g_free (label); } /* @@ -454,7 +416,7 @@ void on_drag_data_received(GtkWidget * /*wgt*/, GdkDragContext * /*context*/, in */ void on_row_changed(GtkTreeModel *tree_model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data) { - SPXMLViewTree *tree = (SPXMLViewTree *)user_data; + SPXMLViewTree *tree = SP_XMLVIEW_TREE(user_data); if (!tree->dndactive) { return; @@ -469,7 +431,7 @@ void on_row_changed(GtkTreeModel *tree_model, GtkTreePath *path, GtkTreeIter *it return; } - GtkTreeRowReference *old_parent_ref = (GtkTreeRowReference *)g_object_get_data (G_OBJECT (tree), "drag-src-path"); + GtkTreeRowReference *old_parent_ref = static_cast<GtkTreeRowReference *>(g_object_get_data (G_OBJECT (tree), "drag-src-path")); if (!old_parent_ref) { //No drag source location g_signal_emit_by_name(G_OBJECT (tree), "tree_move", GUINT_TO_POINTER(0) ); @@ -634,7 +596,7 @@ gboolean do_drag_motion(GtkWidget *widget, GdkDragContext *context, gint x, gint if (path) { action = GDK_ACTION_MOVE; - SPXMLViewTree *tree = (SPXMLViewTree *)user_data; + SPXMLViewTree *tree = SP_XMLVIEW_TREE(user_data); GtkTreeIter iter; gtk_tree_model_get_iter(GTK_TREE_MODEL(tree->store), &iter, path); if (sp_xmlview_tree_node_get_repr (GTK_TREE_MODEL(tree->store), &iter)->type() != Inkscape::XML::ELEMENT_NODE) { @@ -762,3 +724,14 @@ gboolean search_equal_func(GtkTreeModel *model, gint /*column*/, const gchar *ke return !match; } + +/* + 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/sp-xmlview-tree.h b/src/widgets/sp-xmlview-tree.h index e588e78a7..50fcb3bc8 100644 --- a/src/widgets/sp-xmlview-tree.h +++ b/src/widgets/sp-xmlview-tree.h @@ -53,3 +53,14 @@ gboolean sp_xmlview_tree_get_repr_node (SPXMLViewTree * tree, Inkscape::XML::Nod #endif + +/* + 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/spinbutton-events.cpp b/src/widgets/spinbutton-events.cpp index 290b0bb75..7a481aea8 100644 --- a/src/widgets/spinbutton-events.cpp +++ b/src/widgets/spinbutton-events.cpp @@ -3,7 +3,9 @@ * * Authors: * bulia byak <bulia@users.sourceforge.net> + * Jon A. Cruz <jon@joncruz.org> * + * Copyright (C) 2013 authors * Copyright (C) 2003 authors * * Released under GNU GPL, read the file 'COPYING' for more information @@ -20,125 +22,147 @@ #include "sp-widget.h" #include "widget-sizes.h" +#include "spinbutton-events.h" -gboolean -spinbutton_focus_in (GtkWidget *w, GdkEventKey */*event*/, gpointer /*data*/) +gboolean spinbutton_focus_in(GtkWidget *w, GdkEventKey * /*event*/, gpointer /*data*/) { - gdouble *ini; + gdouble *ini = static_cast<gdouble *>(g_object_get_data(G_OBJECT(w), "ini")); + if (ini) { + g_free(ini); // free the old value if any + } - ini = (gdouble *) g_object_get_data(G_OBJECT (w), "ini"); - if (ini) g_free (ini); // free the old value if any + // retrieve the value + ini = g_new(gdouble, 1); + *ini = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); - // retrieve the value - ini = g_new (gdouble, 1); - *ini = gtk_spin_button_get_value (GTK_SPIN_BUTTON(w)); + // remember it + g_object_set_data(G_OBJECT(w), "ini", ini); - // remember it - g_object_set_data (G_OBJECT (w), "ini", ini); - - return FALSE; // I didn't consume the event + return FALSE; // I didn't consume the event } -void -spinbutton_undo (GtkWidget *w) +void spinbutton_undo(GtkWidget *w) { - gdouble *ini = (gdouble *) g_object_get_data(G_OBJECT (w), "ini"); - if (ini) { - gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), *ini); - } + gdouble *ini = static_cast<gdouble *>(g_object_get_data(G_OBJECT(w), "ini")); + if (ini) { + gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), *ini); + } } -void -spinbutton_defocus (GtkWidget *container) +void spinbutton_defocus(GtkWidget *container) { - // defocus spinbuttons by moving focus to the canvas, unless "stay" is on - gboolean stay = GPOINTER_TO_INT(g_object_get_data(G_OBJECT (container), "stay")); - if (stay) { - g_object_set_data (G_OBJECT (container), "stay", GINT_TO_POINTER (FALSE)); - } else { - GtkWidget *canvas = (GtkWidget *) g_object_get_data(G_OBJECT (container), "dtw"); - if (canvas) { - gtk_widget_grab_focus (GTK_WIDGET(canvas)); - } - } + // defocus spinbuttons by moving focus to the canvas, unless "stay" is on + gboolean stay = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(container), "stay")); + if (stay) { + g_object_set_data(G_OBJECT(container), "stay", GINT_TO_POINTER(FALSE)); + } else { + GtkWidget *canvas = GTK_WIDGET(g_object_get_data(G_OBJECT(container), "dtw")); + if (canvas) { + gtk_widget_grab_focus(GTK_WIDGET(canvas)); + } + } } -gboolean -spinbutton_keypress (GtkWidget *w, GdkEventKey *event, gpointer data) +gboolean spinbutton_keypress(GtkWidget *w, GdkEventKey *event, gpointer /*data*/) { - SPWidget *spw = (SPWidget *) data; - gdouble v; - gdouble step; - gdouble page; + gboolean result = FALSE; // I didn't consume the event - switch (get_group0_keyval (event)) { + switch (get_group0_keyval(event)) { case GDK_KEY_Escape: // defocus - spinbutton_undo (w); - spinbutton_defocus(GTK_WIDGET(spw)); - return TRUE; // I consumed the event - break; + spinbutton_undo(w); + spinbutton_defocus(w); + result = TRUE; // I consumed the event + break; case GDK_KEY_Return: // defocus case GDK_KEY_KP_Enter: - spinbutton_defocus (GTK_WIDGET(spw)); - return TRUE; // I consumed the event - break; + spinbutton_defocus(w); + result = TRUE; // I consumed the event + break; case GDK_KEY_Tab: case GDK_KEY_ISO_Left_Tab: - // set the flag meaning "do not leave toolbar when changing value" - g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE)); - return FALSE; // I didn't consume the event - break; + // set the flag meaning "do not leave toolbar when changing value" + g_object_set_data(G_OBJECT(w), "stay", GINT_TO_POINTER(TRUE)); + result = FALSE; // I didn't consume the event + break; - // The following keys are processed manually because GTK implements them in strange ways - // (increments start with double step value and seem to grow as you press the key continuously) + // The following keys are processed manually because GTK implements them in strange ways + // (increments start with double step value and seem to grow as you press the key continuously) case GDK_KEY_Up: case GDK_KEY_KP_Up: - g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE)); - v = gtk_spin_button_get_value(GTK_SPIN_BUTTON (w)); - gtk_spin_button_get_increments(GTK_SPIN_BUTTON (w), &step, &page); - v += step; - gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v); - return TRUE; // I consumed the event - break; + { + g_object_set_data(G_OBJECT(w), "stay", GINT_TO_POINTER(TRUE)); + gdouble v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + gdouble step = 0; + gdouble page = 0; + gtk_spin_button_get_increments(GTK_SPIN_BUTTON(w), &step, &page); + v += step; + gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v); + result = TRUE; // I consumed the event + break; + } case GDK_KEY_Down: case GDK_KEY_KP_Down: - g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE)); - v = gtk_spin_button_get_value(GTK_SPIN_BUTTON (w)); - gtk_spin_button_get_increments(GTK_SPIN_BUTTON (w), &step, &page); - v -= step; - gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v); - return TRUE; // I consumed the event - break; + { + g_object_set_data(G_OBJECT(w), "stay", GINT_TO_POINTER(TRUE)); + gdouble v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + gdouble step = 0; + gdouble page = 0; + gtk_spin_button_get_increments(GTK_SPIN_BUTTON(w), &step, &page); + v -= step; + gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v); + result = TRUE; // I consumed the event + break; + } case GDK_KEY_Page_Up: case GDK_KEY_KP_Page_Up: - g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE)); - v = gtk_spin_button_get_value(GTK_SPIN_BUTTON (w)); - gtk_spin_button_get_increments(GTK_SPIN_BUTTON (w), &step, &page); - v += page; - gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v); - return TRUE; // I consumed the event - break; + { + g_object_set_data(G_OBJECT(w), "stay", GINT_TO_POINTER(TRUE)); + gdouble v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + gdouble step = 0; + gdouble page = 0; + gtk_spin_button_get_increments(GTK_SPIN_BUTTON(w), &step, &page); + v += page; + gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v); + result = TRUE; // I consumed the event + break; + } case GDK_KEY_Page_Down: case GDK_KEY_KP_Page_Down: - g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE)); - v = gtk_spin_button_get_value(GTK_SPIN_BUTTON (w)); - gtk_spin_button_get_increments(GTK_SPIN_BUTTON (w), &step, &page); - v -= page; - gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v); - return TRUE; // I consumed the event - break; + { + g_object_set_data(G_OBJECT(w), "stay", GINT_TO_POINTER(TRUE)); + gdouble v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + gdouble step = 0; + gdouble page = 0; + gtk_spin_button_get_increments(GTK_SPIN_BUTTON(w), &step, &page); + v -= page; + gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), v); + result = TRUE; // I consumed the event + break; + } case GDK_KEY_z: case GDK_KEY_Z: - g_object_set_data (G_OBJECT (spw), "stay", GINT_TO_POINTER(TRUE)); - if (event->state & GDK_CONTROL_MASK) { - spinbutton_undo (w); - return TRUE; // I consumed the event - } - break; + g_object_set_data(G_OBJECT(w), "stay", GINT_TO_POINTER(TRUE)); + if (event->state & GDK_CONTROL_MASK) { + spinbutton_undo(w); + result = TRUE; // I consumed the event + } + break; default: - return FALSE; - break; - } - return FALSE; // I didn't consume the event + result = FALSE; + break; + } + + return result; } + +/* + 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/spiral-toolbar.cpp b/src/widgets/spiral-toolbar.cpp index 34996d24e..08d26f3d1 100644 --- a/src/widgets/spiral-toolbar.cpp +++ b/src/widgets/spiral-toolbar.cpp @@ -28,9 +28,8 @@ # include "config.h" #endif -#include <glibmm/i18n.h> - #include "ui/widget/spinbutton.h" +#include <glibmm/i18n.h> #include "toolbox.h" #include "spiral-toolbar.h" @@ -39,8 +38,6 @@ #include "document-undo.h" #include "../verbs.h" #include "../inkscape.h" -//#include "../interface.h" -//#include "../connection-pool.h" #include "../selection-chemistry.h" #include "../selection.h" #include "../ege-adjustment-action.h" @@ -78,7 +75,7 @@ using Inkscape::UI::PrefPusher; static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustring const &value_name) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -147,15 +144,15 @@ static void sp_spl_tb_defaults(GtkWidget * /*widget*/, GObject *obj) gdouble exp = 1.0; gdouble t0 = 0.0; - adj = (GtkAdjustment*)g_object_get_data(obj, "revolution"); + adj = GTK_ADJUSTMENT(g_object_get_data(obj, "revolution")); gtk_adjustment_set_value(adj, rev); gtk_adjustment_value_changed(adj); - adj = (GtkAdjustment*)g_object_get_data(obj, "expansion"); + adj = GTK_ADJUSTMENT(g_object_get_data(obj, "expansion")); gtk_adjustment_set_value(adj, exp); gtk_adjustment_value_changed(adj); - adj = (GtkAdjustment*)g_object_get_data(obj, "t0"); + adj = GTK_ADJUSTMENT(g_object_get_data(obj, "t0")); gtk_adjustment_set_value(adj, t0); gtk_adjustment_value_changed(adj); @@ -181,17 +178,17 @@ static void spiral_tb_event_attr_changed(Inkscape::XML::Node *repr, g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE)); GtkAdjustment *adj; - adj = (GtkAdjustment*)g_object_get_data(G_OBJECT(tbl), "revolution"); + adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "revolution")); double revolution = 3.0; sp_repr_get_double(repr, "sodipodi:revolution", &revolution); gtk_adjustment_set_value(adj, revolution); - adj = (GtkAdjustment*)g_object_get_data(G_OBJECT(tbl), "expansion"); + adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "expansion")); double expansion = 1.0; sp_repr_get_double(repr, "sodipodi:expansion", &expansion); gtk_adjustment_set_value(adj, expansion); - adj = (GtkAdjustment*)g_object_get_data(G_OBJECT(tbl), "t0"); + adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "t0")); double t0 = 0.0; sp_repr_get_double(repr, "sodipodi:t0", &t0); gtk_adjustment_set_value(adj, t0); @@ -314,7 +311,7 @@ void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_spiral_toolbox_selection_changed), (GObject *)holder)) + sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_spiral_toolbox_selection_changed), holder)) ); g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); diff --git a/src/widgets/spiral-toolbar.h b/src/widgets/spiral-toolbar.h index 3e4d7b46f..194b54bce 100644 --- a/src/widgets/spiral-toolbar.h +++ b/src/widgets/spiral-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index db4decf8e..06850d261 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -28,9 +28,8 @@ # include "config.h" #endif -#include <glibmm/i18n.h> - #include "ui/widget/spinbutton.h" +#include <glibmm/i18n.h> #include "toolbox.h" #include "spray-toolbar.h" @@ -240,7 +239,7 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj InkToggleAction* act = ink_toggle_action_new( "SprayPressureAction", _("Pressure"), _("Use the pressure of the input device to alter the amount of sprayed objects"), - "use_pressure", + 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/spray/usepressure"); diff --git a/src/widgets/spray-toolbar.h b/src/widgets/spray-toolbar.h index 8ac0ec9af..170b6bb8e 100644 --- a/src/widgets/spray-toolbar.h +++ b/src/widgets/spray-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/spw-utilities.cpp b/src/widgets/spw-utilities.cpp index e7db45581..ce8ce388d 100644 --- a/src/widgets/spw-utilities.cpp +++ b/src/widgets/spw-utilities.cpp @@ -19,11 +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 "helper/unit-menu.h" +#include "spw-utilities.h" #include <gtk/gtk.h> @@ -31,8 +37,11 @@ * Creates a label widget with the given text, at the given col, row * position in the table. */ -Gtk::Label * -spw_label(Gtk::Table *table, const gchar *label_text, int col, int row, Gtk::Widget* target) +#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); @@ -47,7 +56,18 @@ spw_label(Gtk::Table *table, const gchar *label_text, int col, int row, Gtk::Wid } 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); + label_widget->set_margin_left(4); + label_widget->set_margin_right(4); + 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; } @@ -60,8 +80,19 @@ spw_label_old(GtkWidget *table, const gchar *label_text, int col, int row) g_assert(label_widget != NULL); gtk_misc_set_alignment (GTK_MISC (label_widget), 1.0, 0.5); gtk_widget_show (label_widget); - gtk_table_attach (GTK_TABLE (table), label_widget, col, col+1, row, row+1, + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_left(label_widget, 4); + gtk_widget_set_margin_right(label_widget, 4); + gtk_widget_set_hexpand(label_widget, TRUE); + 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; } @@ -69,14 +100,26 @@ 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. */ -Gtk::HBox * -spw_hbox(Gtk::Table * table, int width, int col, int row) +#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; } @@ -116,16 +159,33 @@ spw_checkbutton(GtkWidget * dialog, GtkWidget * table, g_assert(dialog != NULL); g_assert(table != NULL); - GtkWidget *l = gtk_label_new (label); - gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); - gtk_widget_show (l); + GtkWidget *l = gtk_label_new (label); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + 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); g_signal_connect (G_OBJECT (b), "toggled", cb, dialog); @@ -152,8 +212,17 @@ 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; } @@ -188,13 +257,22 @@ spw_unit_selector(GtkWidget * dialog, GtkWidget * table, GtkWidget * sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1.0, 4); g_assert(sb != NULL); gtk_widget_show (sb); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(sb, GTK_ALIGN_FILL); + gtk_widget_set_hexpand(sb, TRUE); + gtk_widget_set_valign(sb, GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(table), sb, 1, row, 1, 1); +#else gtk_table_attach (GTK_TABLE (table), sb, 1, 2, row, row+1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 0, 0); +#endif + g_signal_connect (G_OBJECT (a), "value_changed", cb, dialog); return sb; } -void +static void sp_set_font_size_recursive (GtkWidget *w, gpointer font) { guint size = GPOINTER_TO_UINT (font); diff --git a/src/widgets/spw-utilities.h b/src/widgets/spw-utilities.h index 263abbcaf..fb8c04ebf 100644 --- a/src/widgets/spw-utilities.h +++ b/src/widgets/spw-utilities.h @@ -20,18 +20,26 @@ namespace Gtk { class Label; + +#if GTK_CHECK_VERSION(3,0,0) + class Grid; +#else class Table; +#endif + class HBox; class Widget; } -Gtk::Label * -spw_label(Gtk::Table *table, gchar const *label_text, int col, int row, Gtk::Widget *target); -GtkWidget * -spw_label_old(GtkWidget *table, gchar const *label_text, int col, int row); +#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 -Gtk::HBox * -spw_hbox(Gtk::Table *table, int width, int col, int row); +GtkWidget * spw_label_old(GtkWidget *table, gchar const *label_text, int col, int row); GtkWidget * spw_vbox_checkbutton(GtkWidget *dialog, GtkWidget *table, diff --git a/src/widgets/star-toolbar.cpp b/src/widgets/star-toolbar.cpp index 61d8e1000..8c07c6473 100644 --- a/src/widgets/star-toolbar.cpp +++ b/src/widgets/star-toolbar.cpp @@ -28,9 +28,8 @@ # include "config.h" #endif -#include <glibmm/i18n.h> - #include "ui/widget/spinbutton.h" +#include <glibmm/i18n.h> #include "toolbox.h" #include "star-toolbar.h" @@ -74,7 +73,7 @@ using Inkscape::UI::PrefPusher; static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKludge ) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { // do not remember prefs if this call is initiated by an undo change, because undoing object @@ -120,7 +119,7 @@ static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKlu static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKludge ) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { if (!IS_NAN(gtk_adjustment_get_value(adj))) { @@ -173,7 +172,7 @@ static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKl static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *dataKludge ) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); bool flat = ege_select_one_action_get_active( act ) == 0; if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { @@ -218,7 +217,7 @@ static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *d static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludge ) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -257,7 +256,7 @@ static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludg static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKludge ) { - SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" ); + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -337,7 +336,7 @@ static void star_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *n gtk_action_set_sensitive( prop_action, FALSE ); } } else if ((!strcmp(name, "sodipodi:r1") || !strcmp(name, "sodipodi:r2")) && (!isFlatSided) ) { - adj = (GtkAdjustment*)g_object_get_data(G_OBJECT(tbl), "proportion"); + adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "proportion")); gdouble r1 = 1.0; gdouble r2 = 1.0; sp_repr_get_double(repr, "sodipodi:r1", &r1); @@ -348,7 +347,7 @@ static void star_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *n gtk_adjustment_set_value(adj, r1/r2); } } else if (!strcmp(name, "sodipodi:sides")) { - adj = (GtkAdjustment*)g_object_get_data(G_OBJECT(tbl), "magnitude"); + adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "magnitude")); int sides = 0; sp_repr_get_int(repr, "sodipodi:sides", &sides); gtk_adjustment_set_value(adj, sides); @@ -584,7 +583,7 @@ void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje } sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), (GObject *)holder)) + sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), holder)) ); g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); diff --git a/src/widgets/star-toolbar.h b/src/widgets/star-toolbar.h index 793f73f8b..6f91d5570 100644 --- a/src/widgets/star-toolbar.h +++ b/src/widgets/star-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/stroke-marker-selector.cpp b/src/widgets/stroke-marker-selector.cpp index cada81f7b..62fa47603 100644 --- a/src/widgets/stroke-marker-selector.cpp +++ b/src/widgets/stroke-marker-selector.cpp @@ -40,12 +40,15 @@ #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; -MarkerComboBox::MarkerComboBox(gchar const *id) : +MarkerComboBox::MarkerComboBox(gchar const *id, int l) : Gtk::ComboBox(), combo_id(id), + loc(l), updating(false), markerCount(0) { @@ -54,8 +57,8 @@ MarkerComboBox::MarkerComboBox(gchar const *id) : set_model(marker_store); pack_start(image_renderer, false); pack_end(label_renderer, true); - label_renderer.set_padding(5, 0); - image_renderer.set_padding(5, 0); + label_renderer.set_padding(2, 0); + image_renderer.set_padding(2, 0); set_cell_data_func(label_renderer, sigc::mem_fun(*this, &MarkerComboBox::prepareLabelRenderer)); 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); @@ -205,20 +208,8 @@ void MarkerComboBox::set_current(SPObject *marker) updating = true; if (marker != NULL) { - bool mark_is_stock = false; - if (marker->getRepr()->attribute("inkscape:stockid")) { - mark_is_stock = true; - } - - gchar *markname = 0; - if (mark_is_stock) { - markname = g_strdup(marker->getRepr()->attribute("inkscape:stockid")); - } else { - markname = g_strdup(marker->getRepr()->attribute("id")); - } - + gchar *markname = g_strdup(marker->getRepr()->attribute("id")); set_selected(markname); - g_free (markname); } else { @@ -253,7 +244,7 @@ const gchar * MarkerComboBox::get_active_marker_uri() { markurn = g_strdup(markid); } - SPObject *mark = get_stock_item(markurn); + SPObject *mark = get_stock_item(markurn, stockid); g_free(markurn); if (mark) { Inkscape::XML::Node *repr = mark->getRepr(); @@ -266,9 +257,17 @@ const gchar * MarkerComboBox::get_active_marker_uri() return marker; } - void MarkerComboBox::set_active_history() { - set_selected(get_active()->get_value(marker_columns.marker)); + + const gchar *markid = get_active()->get_value(marker_columns.marker); + + // If forked from a stockid, add the stockid + SPObject const *marker = doc->getObjectById(markid); + if (marker && marker->getRepr()->attribute("inkscape:stockid")) { + markid = marker->getRepr()->attribute("inkscape:stockid"); + } + + set_selected(markid); } @@ -399,10 +398,10 @@ void MarkerComboBox::add_markers (GSList *marker_list, SPDocument *source, gbool for (; marker_list != NULL; marker_list = marker_list->next) { Inkscape::XML::Node *repr = reinterpret_cast<SPItem *>(marker_list->data)->getRepr(); - gchar const *markid = repr->attribute("id"); + gchar const *markid = repr->attribute("inkscape:stockid") ? repr->attribute("inkscape:stockid") : repr->attribute("id"); // generate preview - Gtk::Image *prv = create_marker_image (22, markid, source, drawing, visionkey); + Gtk::Image *prv = create_marker_image (22, repr->attribute("id"), source, drawing, visionkey); prv->show(); // Add history before separator, others after @@ -413,8 +412,10 @@ void MarkerComboBox::add_markers (GSList *marker_list, SPDocument *source, gbool row = *(marker_store->append()); row[marker_columns.label] = gr_ellipsize_text(markid, 20); + // Non "stock" markers can also have "inkscape:stockid" (when using extension ColorMarkers), + // So use !is_history instead to determine is it is "stock" (ie in the markers.svg file) row[marker_columns.stock] = !history; - row[marker_columns.marker] = g_strdup(markid); + row[marker_columns.marker] = repr->attribute("id"); row[marker_columns.image] = prv; row[marker_columns.history] = history; row[marker_columns.separator] = false; @@ -424,6 +425,37 @@ void MarkerComboBox::add_markers (GSList *marker_list, SPDocument *source, gbool sandbox->getRoot()->invoke_hide(visionkey); } +/* + * Remove from the cache and recreate a marker image + */ +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); + 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); + if (prv) { + prv->show(); + } + sandbox->getRoot()->invoke_hide(visionkey); + + for(Gtk::TreeIter iter = marker_store->children().begin(); + iter != marker_store->children().end(); ++iter) { + Gtk::TreeModel::Row row = (*iter); + if (row[marker_columns.marker] && row[marker_columns.history] && + !strcmp(row[marker_columns.marker], mname)) { + row[marker_columns.image] = prv; + return; + } + } + +} /** * Creates a copy of the marker named mname, determines its visible and renderable * area in the bounding box, and then renders it. This allows us to fill in @@ -456,6 +488,38 @@ MarkerComboBox::create_marker_image(unsigned psize, gchar const *mname, Inkscape::GC::release(mrepr); + // If the marker color is a url link to a pattern or gradient copy that too + SPObject *mk = source->getObjectById(mname); + SPCSSAttr *css_marker = sp_css_attr_from_object(mk->firstChild(), SP_STYLE_FLAG_ALWAYS); + //const char *mfill = sp_repr_css_property(css_marker, "fill", "none"); + const char *mstroke = sp_repr_css_property(css_marker, "fill", "none"); + + if (!strncmp (mstroke, "url(", 4)) { + SPObject *linkObj = getMarkerObj(mstroke, source); + if (linkObj) { + Inkscape::XML::Node *grepr = linkObj->getRepr()->duplicate(xml_doc); + SPObject *oldmarker = sandbox->getObjectById(linkObj->getId()); + if (oldmarker) { + oldmarker->deleteObject(false); + } + defsrepr->appendChild(grepr); + Inkscape::GC::release(grepr); + + if (SP_IS_GRADIENT(linkObj)) { + SPGradient *vector = sp_gradient_get_forked_vector_if_necessary (SP_GRADIENT(linkObj), false); + if (vector) { + Inkscape::XML::Node *grepr = vector->getRepr()->duplicate(xml_doc); + SPObject *oldmarker = sandbox->getObjectById(vector->getId()); + if (oldmarker) { + oldmarker->deleteObject(false); + } + defsrepr->appendChild(grepr); + Inkscape::GC::release(grepr); + } + } + } + } + // Uncomment this to get the sandbox documents saved (useful for debugging) //FILE *fp = fopen (g_strconcat(combo_id, mname, ".svg", NULL), "w"); //sp_repr_save_stream(sandbox->getReprDoc(), fp); @@ -498,6 +562,7 @@ MarkerComboBox::create_marker_image(unsigned psize, gchar const *mname, void MarkerComboBox::prepareLabelRenderer( Gtk::TreeModel::const_iterator const &row ) { Glib::ustring name=(*row)[marker_columns.label]; label_renderer.property_markup() = name.c_str(); + label_renderer.property_scale() = 0.8; } void MarkerComboBox::prepareImageRenderer( Gtk::TreeModel::const_iterator const &row ) { diff --git a/src/widgets/stroke-marker-selector.h b/src/widgets/stroke-marker-selector.h index 9f79b7c1e..02038ea42 100644 --- a/src/widgets/stroke-marker-selector.h +++ b/src/widgets/stroke-marker-selector.h @@ -32,7 +32,7 @@ class Adjustment; class MarkerComboBox : public Gtk::ComboBox { public: - MarkerComboBox(gchar const *id); + MarkerComboBox(gchar const *id, int loc); ~MarkerComboBox(); void setDesktop(SPDesktop *desktop); @@ -45,12 +45,15 @@ public: const gchar *get_active_marker_uri(); bool update() { return updating; }; gchar const *get_id() { return combo_id; }; + void update_marker_image(gchar const *mname); + int get_loc() { return loc; }; private: Glib::RefPtr<Gtk::ListStore> marker_store; gchar const *combo_id; + int loc; bool updating; guint markerCount; SPDesktop *desktop; diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 695c16ced..c6934f0a6 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -18,6 +18,10 @@ #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" using Inkscape::DocumentUndo; @@ -45,8 +49,71 @@ void sp_stroke_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop) } } + +/** + * Extract the actual name of the link + * e.g. get mTriangle from url(#mTriangle). + * \return Buffer containing the actual name, allocated from GLib; + * the caller should free the buffer when they no longer need it. + */ +SPObject* getMarkerObj(gchar const *n, SPDocument *doc) +{ + gchar const *p = n; + while (*p != '\0' && *p != '#') { + p++; + } + + if (*p == '\0' || p[1] == '\0') { + return NULL; + } + + p++; + int c = 0; + while (p[c] != '\0' && p[c] != ')') { + c++; + } + + if (p[c] == '\0') { + return NULL; + } + + gchar* b = g_strdup(p); + b[c] = '\0'; + + // FIXME: get the document from the object and let the caller pass it in + SPObject *marker = doc->getObjectById(b); + return marker; +} + namespace Inkscape { + +/** + * Construct a stroke-style radio button with a given icon + * + * \param[in] grp The Gtk::RadioButtonGroup to which to add the new button + * \param[in] icon The icon to use for the button + * \param[in] button_type The type of stroke-style radio button (join/cap) + * \param[in] stroke_style The style attribute to associate with the button + */ +StrokeStyle::StrokeStyleButton::StrokeStyleButton(Gtk::RadioButtonGroup &grp, + char const *icon, + StrokeStyleButtonType button_type, + gchar const *stroke_style) + : + Gtk::RadioButton(grp), + button_type(button_type), + stroke_style(stroke_style) +{ + show(); + set_mode(false); + + Gtk::Widget *px = manage(Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_LARGE_TOOLBAR, icon))); + g_assert(px != NULL); + px->show(); + add(*px); +} + /** * Create the fill or stroke style widget, and hook up all the signals. */ @@ -82,10 +149,17 @@ StrokeStyle::StrokeStyle() : 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->show(); table->set_border_width(4); table->set_row_spacings(4); +#endif + + table->show(); f->add(*table); gint i = 0; @@ -147,24 +221,27 @@ StrokeStyle::StrokeStyle() : hb = spw_hbox(table, 3, 1, i); - //tb = NULL; + Gtk::RadioButtonGroup joinGrp; + + joinMiter = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-miter"), + hb, STROKE_STYLE_BUTTON_JOIN, "miter"); - joinMiter = makeRadioButton(NULL, INKSCAPE_ICON("stroke-join-miter"), - hb, "join", "miter"); // TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. // For an example, draw a triangle with a large stroke width and modify the // "Join" option (in the Fill and Stroke dialog). joinMiter->set_tooltip_text(_("Miter join")); - joinRound = makeRadioButton(joinMiter, INKSCAPE_ICON("stroke-join-round"), - hb, "join", "round"); + joinRound = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-round"), + hb, STROKE_STYLE_BUTTON_JOIN, "round"); + // TRANSLATORS: Round join: joining lines with a rounded corner. // For an example, draw a triangle with a large stroke width and modify the // "Join" option (in the Fill and Stroke dialog). joinRound->set_tooltip_text(_("Round join")); - joinBevel = makeRadioButton(joinMiter, INKSCAPE_ICON("stroke-join-bevel"), - hb, "join", "bevel"); + joinBevel = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-bevel"), + hb, STROKE_STYLE_BUTTON_JOIN, "bevel"); + // TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. // For an example, draw a triangle with a large stroke width and modify the // "Join" option (in the Fill and Stroke dialog). @@ -213,20 +290,25 @@ StrokeStyle::StrokeStyle() : hb = spw_hbox(table, 3, 1, i); - capButt = makeRadioButton(capButt, INKSCAPE_ICON("stroke-cap-butt"), - hb, "cap", "butt"); + Gtk::RadioButtonGroup capGrp; + + capButt = makeRadioButton(capGrp, INKSCAPE_ICON("stroke-cap-butt"), + hb, STROKE_STYLE_BUTTON_CAP, "butt"); + // TRANSLATORS: Butt cap: the line shape does not extend beyond the end point // of the line; the ends of the line are square capButt->set_tooltip_text(_("Butt cap")); - capRound = makeRadioButton(capButt, INKSCAPE_ICON("stroke-cap-round"), - hb, "cap", "round"); + capRound = makeRadioButton(capGrp, INKSCAPE_ICON("stroke-cap-round"), + hb, STROKE_STYLE_BUTTON_CAP, "round"); + // TRANSLATORS: Round cap: the line shape extends beyond the end point of the // line; the ends of the line are rounded capRound->set_tooltip_text(_("Round cap")); - capSquare = makeRadioButton(capButt, INKSCAPE_ICON("stroke-cap-square"), - hb, "cap", "square"); + capSquare = makeRadioButton(capGrp, INKSCAPE_ICON("stroke-cap-square"), + hb, STROKE_STYLE_BUTTON_CAP, "square"); + // TRANSLATORS: Square cap: the line shape extends beyond the end point of the // line; the ends of the line are square capSquare->set_tooltip_text(_("Square cap")); @@ -242,7 +324,16 @@ StrokeStyle::StrokeStyle() : dashSelector = 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++; @@ -251,34 +342,61 @@ StrokeStyle::StrokeStyle() : // TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes // (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. - startMarkerCombo = manage(new MarkerComboBox("marker-start")); + startMarkerCombo = manage(new MarkerComboBox("marker-start", SP_MARKER_LOC_START)); spw_label(table, _("_Start Markers:"), 0, i, startMarkerCombo); startMarkerCombo->set_tooltip_text(_("Start Markers are drawn on the first node of a path or shape")); startMarkerConn = startMarkerCombo->signal_changed().connect( sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( sigc::ptr_fun(&StrokeStyle::markerSelectCB), startMarkerCombo, this, SP_MARKER_LOC_START)); startMarkerCombo->show(); + +#if WITH_GTKMM_3_0 + startMarkerCombo->set_hexpand(); + startMarkerCombo->set_halign(Gtk::ALIGN_FILL); + startMarkerCombo->set_valign(Gtk::ALIGN_CENTER); + table->attach(*startMarkerCombo, 1, i, 3, 1); +#else table->attach(*startMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0); +#endif + i++; - midMarkerCombo = manage(new MarkerComboBox("marker-mid")); + midMarkerCombo = manage(new MarkerComboBox("marker-mid", SP_MARKER_LOC_MID)); spw_label(table, _("_Mid Markers:"), 0, i, midMarkerCombo); midMarkerCombo->set_tooltip_text(_("Mid Markers are drawn on every node of a path or shape except the first and last nodes")); midMarkerConn = midMarkerCombo->signal_changed().connect( sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( sigc::ptr_fun(&StrokeStyle::markerSelectCB), midMarkerCombo, this, SP_MARKER_LOC_MID)); midMarkerCombo->show(); + +#if WITH_GTKMM_3_0 + midMarkerCombo->set_hexpand(); + midMarkerCombo->set_halign(Gtk::ALIGN_FILL); + midMarkerCombo->set_valign(Gtk::ALIGN_CENTER); + table->attach(*midMarkerCombo, 1, i, 3, 1); +#else table->attach(*midMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0); +#endif + i++; - endMarkerCombo = manage(new MarkerComboBox("marker-end")); + endMarkerCombo = manage(new MarkerComboBox("marker-end", SP_MARKER_LOC_END)); spw_label(table, _("_End Markers:"), 0, i, endMarkerCombo); endMarkerCombo->set_tooltip_text(_("End Markers are drawn on the last node of a path or shape")); endMarkerConn = endMarkerCombo->signal_changed().connect( sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( sigc::ptr_fun(&StrokeStyle::markerSelectCB), endMarkerCombo, this, SP_MARKER_LOC_END)); endMarkerCombo->show(); + +#if WITH_GTKMM_3_0 + endMarkerCombo->set_hexpand(); + endMarkerCombo->set_halign(Gtk::ALIGN_FILL); + endMarkerCombo->set_valign(Gtk::ALIGN_CENTER); + table->attach(*endMarkerCombo, 1, i, 3, 1); +#else table->attach(*endMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0); +#endif + i++; setDesktop(desktop); @@ -311,40 +429,36 @@ void StrokeStyle::setDesktop(SPDesktop *desktop) /** - * Helper function for creating radio buttons. This should probably be re-thought out - * when reimplementing this with Gtkmm. + * Helper function for creating stroke-style radio buttons. + * + * \param[in] grp The Gtk::RadioButtonGroup in which to add the button + * \param[in] icon The icon for the button + * \param[in] hb The Gtk::Box container in which to add the button + * \param[in] button_type The type (join/cap) for the button + * \param[in] stroke_style The style attribute to associate with the button + * + * \details After instantiating the button, it is added to a container box and + * a handler for the toggle event is connected. */ -Gtk::RadioButton * -StrokeStyle::makeRadioButton(Gtk::RadioButton *tb, char const *icon, - Gtk::HBox *hb, gchar const *key, gchar const *data) +StrokeStyle::StrokeStyleButton * +StrokeStyle::makeRadioButton(Gtk::RadioButtonGroup &grp, + char const *icon, + Gtk::HBox *hb, + StrokeStyleButtonType button_type, + gchar const *stroke_style) { g_assert(icon != NULL); g_assert(hb != NULL); - if (tb == NULL) { - tb = new Gtk::RadioButton(); - } else { - Gtk::RadioButtonGroup grp = tb->get_group(); - tb = new Gtk::RadioButton(grp); - } + StrokeStyleButton *tb = new StrokeStyleButton(grp, icon, button_type, stroke_style); - tb->show(); - tb->set_mode(false); hb->pack_start(*tb, false, false, 0); - // TODO set_data(icon, tb); - tb->set_data(key, (gpointer*)data); - tb->signal_toggled().connect(sigc::bind<Gtk::RadioButton *, StrokeStyle *>( + tb->signal_toggled().connect(sigc::bind<StrokeStyleButton *, StrokeStyle *>( sigc::ptr_fun(&StrokeStyle::buttonToggledCB), tb, this)); - Gtk::Widget *px = manage(Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_LARGE_TOOLBAR, icon))); - g_assert(px != NULL); - px->show(); - tb->add(*px); - return tb; - } /** @@ -352,13 +466,14 @@ StrokeStyle::makeRadioButton(Gtk::RadioButton *tb, char const *icon, * Gets the marker uri string and applies it to all selected * items in the current desktop. */ -void -StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMarkerLoc const which) +void StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMarkerLoc const /*which*/) { if (spw->update) { return; } + spw->update = true; + SPDocument *document = sp_desktop_document(spw->desktop); if (!document) { return; @@ -367,6 +482,7 @@ StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMa /* Get Marker */ gchar const *marker = marker_combo->get_active_marker_uri(); + SPCSSAttr *css = sp_repr_css_attr_new(); gchar const *combo_id = marker_combo->get_id(); sp_repr_css_set_property(css, combo_id, marker); @@ -374,7 +490,7 @@ StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMa // Also update the marker combobox, so the document's markers // show up at the top of the combobox // sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? sp_desktop_selection(desktop) : NULL); - spw->updateMarkerHist(which); + //spw->updateMarkerHist(which); Inkscape::Selection *selection = sp_desktop_selection(spw->desktop); GSList const *items = selection->itemList(); @@ -386,22 +502,24 @@ StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMa Inkscape::XML::Node *selrepr = item->getRepr(); if (selrepr) { sp_repr_css_change_recursive(selrepr, css, "style"); + SPObject *markerObj = getMarkerObj(marker, document); + spw->setMarkerColor(markerObj, marker_combo->get_loc(), item); } + item->requestModified(SP_OBJECT_MODIFIED_FLAG); item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + + DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, _("Set markers")); } sp_repr_css_attr_unref(css); css = 0; - DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, - _("Set markers")); - + spw->update = false; }; -void -StrokeStyle::updateMarkerHist(SPMarkerLoc const which) { - +void StrokeStyle::updateMarkerHist(SPMarkerLoc const which) +{ switch (which) { case SP_MARKER_LOC_START: startMarkerConn.block(); @@ -463,8 +581,9 @@ gboolean StrokeStyle::setStrokeWidthUnit(SPUnitSelector *, gdouble average = stroke_average_width (objects); - if (average == Geom::infinity() || average == 0) + if ((average == Geom::infinity()) || (average < 1e-8)){ //less than 1e-8: to campare against zero, while taking numeric accuracy into account return FALSE; + } #if WITH_GTKMM_3_0 (*spw->widthAdj)->set_value(100.0 * w / average); @@ -518,6 +637,166 @@ StrokeStyle::selectionChangedCB() updateLine(); } +/* + * Fork marker if necessary and set the referencing items url to the new marker + * Return the new marker + */ +SPObject * +StrokeStyle::forkMarker(SPObject *marker, int loc, SPItem *item) +{ + if (!item || !marker) { + return NULL; + } + + gchar const *marker_id = SPMarkerNames[loc].key; + + /* + * Optimization when all the references to this marker are from this item + * then we can reuse it and dont need to fork + */ + Glib::ustring urlId = Glib::ustring::format("url(#", marker->getRepr()->attribute("id"), ")"); + unsigned int refs = 0; + for (int i = SP_MARKER_LOC_START; i < SP_MARKER_LOC_QTY; i++) { + if (item->style->marker[i].set && !strcmp(urlId.c_str(), item->style->marker[i].value)) { + refs++; + } + } + if (marker->hrefcount <= refs) { + return marker; + } + + marker = sp_marker_fork_if_necessary(marker); + + // Update the items url to new marker + Inkscape::XML::Node *mark_repr = marker->getRepr(); + SPCSSAttr *css_item = sp_repr_css_attr_new(); + sp_repr_css_set_property(css_item, marker_id, g_strconcat("url(#", mark_repr->attribute("id"), ")", NULL)); + sp_repr_css_change_recursive(item->getRepr(), css_item, "style"); + + sp_repr_css_attr_unref(css_item); + css_item = 0; + + return marker; +} + +/** + * Change the color of the marker to match the color of the item. + * Marker stroke color is set to item stroke color. + * Fill color : + * 1. If the item has fill, use that for the marker fill, + * 2. If the marker has same fill and stroke assume its solid, use item stroke for both fill and stroke the line stroke + * 3. If the marker has fill color, use the marker fill color + * + */ +void +StrokeStyle::setMarkerColor(SPObject *marker, int loc, SPItem *item) +{ + + if (!item || !marker) { + return; + } + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean colorStock = prefs->getBool("/options/markers/colorStockMarkers", true); + gboolean colorCustom = prefs->getBool("/options/markers/colorCustomMarkers", false); + const gchar *stock = marker->getRepr()->attribute("inkscape:isstock"); + gboolean isStock = (stock && !strcmp(stock,"true")); + + if (isStock ? !colorStock : !colorCustom) { + return; + } + + // Check if we need to fork this marker + marker = forkMarker(marker, loc, item); + + Inkscape::XML::Node *repr = marker->getRepr()->firstChild(); + if (!repr) { + return; + }; + + // Current line style + SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); + const char *lstroke = getItemColorForMarker(item, FOR_STROKE, loc); + const char *lstroke_opacity = sp_repr_css_property(css_item, "stroke-opacity", "1"); + const char *lfill = getItemColorForMarker(item, FOR_FILL, loc); + const char *lfill_opacity = sp_repr_css_property(css_item, "fill-opacity", "1"); + + // Current marker style + SPCSSAttr *css_marker = sp_css_attr_from_object(marker->firstChild(), SP_STYLE_FLAG_ALWAYS); + const char *mfill = sp_repr_css_property(css_marker, "fill", "none"); + const char *mstroke = sp_repr_css_property(css_marker, "fill", "none"); + + // Create new marker style with the lines stroke + SPCSSAttr *css = sp_repr_css_attr_new(); + + sp_repr_css_set_property(css, "stroke", lstroke); + sp_repr_css_set_property(css, "stroke-opacity", lstroke_opacity); + + if (strcmp(lfill, "none") ) { + // 1. If the line has fill, use that for the marker fill + sp_repr_css_set_property(css, "fill", lfill); + sp_repr_css_set_property(css, "fill-opacity", lfill_opacity); + } + else if (mfill && mstroke && !strcmp(mfill, mstroke) && mfill[0] == '#' && strcmp(mfill, "#ffffff")) { + // 2. If the marker has same fill and stroke assume its solid. use line stroke for both fill and stroke the line stroke + sp_repr_css_set_property(css, "fill", lstroke); + sp_repr_css_set_property(css, "fill-opacity", lstroke_opacity); + } + else if (mfill && mfill[0] == '#' && strcmp(mfill, "#000000")) { + // 3. If the marker has fill color, use the marker fill color + sp_repr_css_set_property(css, "fill", mfill); + //sp_repr_css_set_property(css, "fill-opacity", mfill_opacity); + } + + sp_repr_css_change_recursive(marker->firstChild()->getRepr(), css, "style"); + + // Tell the combos to update its image cache of this marker + gchar const *mid = marker->getRepr()->attribute("id"); + startMarkerCombo->update_marker_image(mid); + midMarkerCombo->update_marker_image(mid); + endMarkerCombo->update_marker_image(mid); + + sp_repr_css_attr_unref(css); + css = 0; + + +} + +/* + * Get the fill or stroke color of the item + * If its a gradient, then return first or last stop color + */ +const char * +StrokeStyle::getItemColorForMarker(SPItem *item, Inkscape::PaintTarget fill_or_stroke, int loc) +{ + SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); + const char *color; + if (fill_or_stroke == FOR_FILL) + color = sp_repr_css_property(css_item, "fill", "none"); + else + color = sp_repr_css_property(css_item, "stroke", "none"); + + if (!strncmp (color, "url(", 4)) { + // If the item has a gradient use the first stop color for the marker + + SPGradient *grad = getGradient(item, fill_or_stroke); + if (grad) { + SPGradient *vector = grad->getVector(FALSE); + SPStop *stop = vector->getFirstStop(); + if (loc == SP_MARKER_LOC_END) { + stop = sp_last_stop(vector); + } + if (stop) { + guint32 const c1 = sp_stop_get_rgba32(stop); + gchar c[64]; + sp_svg_write_color(c, sizeof(c), c1); + color = g_strdup(c); + //lstroke_opacity = Glib::ustring::format(stop->opacity).c_str(); + } + } + } + return color; +} /** * Sets selector widgets' dash style from an SPStyle object. */ @@ -602,7 +881,6 @@ StrokeStyle::updateLine() Inkscape::Selection *sel = desktop ? sp_desktop_selection(desktop) : NULL; - // TODO FillOrStroke kind = GPOINTER_TO_INT(get_data("kind")) ? FILL : STROKE; // create temporary style @@ -874,39 +1152,30 @@ StrokeStyle::lineDashChangedCB() * calls the respective routines to update css properties, etc. * */ -void StrokeStyle::buttonToggledCB(Gtk::ToggleButton *tb, StrokeStyle *spw) +void StrokeStyle::buttonToggledCB(StrokeStyleButton *tb, StrokeStyle *spw) { if (spw->update) { return; } if (tb->get_active()) { - - // TODO - gchar const *join - = static_cast<gchar const *>(tb->get_data("join")); - gchar const *cap - = static_cast<gchar const *>(tb->get_data("cap")); - - if (join) { - spw->miterLimitSpin->set_sensitive(!strcmp(join, "miter")); + if (tb->get_button_type() == STROKE_STYLE_BUTTON_JOIN) { + spw->miterLimitSpin->set_sensitive(!strcmp(tb->get_stroke_style(), "miter")); } /* TODO: Create some standardized method */ SPCSSAttr *css = sp_repr_css_attr_new(); - if (join) { - sp_repr_css_set_property(css, "stroke-linejoin", join); - - sp_desktop_set_style (spw->desktop, css); - - spw->setJoinButtons(tb); - } else if (cap) { - sp_repr_css_set_property(css, "stroke-linecap", cap); - - sp_desktop_set_style (spw->desktop, css); - - spw->setCapButtons(tb); + switch (tb->get_button_type()) { + case STROKE_STYLE_BUTTON_JOIN: + sp_repr_css_set_property(css, "stroke-linejoin", tb->get_stroke_style()); + sp_desktop_set_style (spw->desktop, css); + spw->setJoinButtons(tb); + break; + case STROKE_STYLE_BUTTON_CAP: + sp_repr_css_set_property(css, "stroke-linecap", tb->get_stroke_style()); + sp_desktop_set_style (spw->desktop, css); + spw->setCapButtons(tb); } sp_repr_css_attr_unref(css); @@ -988,10 +1257,22 @@ StrokeStyle::updateAllMarkers(GSList const *objects) // If the object has this type of markers, // Extract the name of the marker that the object uses - SPObject *marker = getMarkerName(object->style->marker[keyloc[i].loc].value, object->document); + SPObject *marker = getMarkerObj(object->style->marker[keyloc[i].loc].value, object->document); // Scroll the combobox to that marker combo->set_current(marker); + // Set the marker color + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean update = prefs->getBool("/options/markers/colorUpdateMarkers", true); + + if (update) { + setMarkerColor(marker, combo->get_loc(), SP_ITEM(object)); + + SPDocument *document = sp_desktop_document(desktop); + DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, + _("Set marker color")); + } + } else { combo->set_current(NULL); } @@ -1000,41 +1281,6 @@ StrokeStyle::updateAllMarkers(GSList const *objects) } -/** - * Extract the actual name of the link - * e.g. get mTriangle from url(#mTriangle). - * \return Buffer containing the actual name, allocated from GLib; - * the caller should free the buffer when they no longer need it. - */ -SPObject* -StrokeStyle::getMarkerName(gchar const *n, SPDocument *doc) -{ - gchar const *p = n; - while (*p != '\0' && *p != '#') { - p++; - } - - if (*p == '\0' || p[1] == '\0') { - return NULL; - } - - p++; - int c = 0; - while (p[c] != '\0' && p[c] != ')') { - c++; - } - - if (p[c] == '\0') { - return NULL; - } - - gchar* b = g_strdup(p); - b[c] = '\0'; - - // FIXME: get the document from the object and let the caller pass it in - SPObject *marker = doc->getObjectById(b); - return marker; -} } // namespace Inkscape diff --git a/src/widgets/stroke-style.h b/src/widgets/stroke-style.h index fe06e5b81..fd9940db1 100644 --- a/src/widgets/stroke-style.h +++ b/src/widgets/stroke-style.h @@ -15,9 +15,19 @@ #ifndef SEEN_DIALOGS_STROKE_STYLE_H #define SEEN_DIALOGS_STROKE_STYLE_H +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #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> #include "desktop.h" @@ -35,6 +45,7 @@ #include "inkscape.h" #include "io/sys.h" #include "marker.h" +#include "preferences.h" #include "path-prefix.h" #include "selection.h" #include "sp-linear-gradient.h" @@ -66,6 +77,15 @@ class Widget; class Container; } +struct { gchar const *key; gint value; } const SPMarkerNames[] = { + {"marker-all", SP_MARKER_LOC}, + {"marker-start", SP_MARKER_LOC_START}, + {"marker-mid", SP_MARKER_LOC_MID}, + {"marker-end", SP_MARKER_LOC_END}, + {"", SP_MARKER_LOC_QTY}, + {NULL, -1} +}; + /** * Creates an instance of a paint style widget. */ @@ -81,7 +101,10 @@ Gtk::Widget *sp_stroke_style_line_widget_new(void); */ void sp_stroke_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop); +SPObject *getMarkerObj(gchar const *n, SPDocument *doc); + namespace Inkscape { +class StrokeStyleButton; class StrokeStyle : public Gtk::VBox { @@ -91,8 +114,34 @@ public: void setDesktop(SPDesktop *desktop); private: + /** List of valid types for the stroke-style radio-button widget */ + enum StrokeStyleButtonType { + STROKE_STYLE_BUTTON_JOIN, ///< A button to set the line-join style + STROKE_STYLE_BUTTON_CAP ///< A button to set the line-cap style + }; + + /** + * A custom radio-button for setting the stroke style. It can be configured + * to set either the join or cap style by setting the button_type field. + */ + class StrokeStyleButton : public Gtk::RadioButton { + public: + StrokeStyleButton(Gtk::RadioButtonGroup &grp, + char const *icon, + StrokeStyleButtonType button_type, + gchar const *stroke_style); + + /** Get the type (line/cap) of the stroke-style button */ + inline StrokeStyleButtonType get_button_type() {return button_type;} + + /** Get the stroke style attribute associated with the button */ + inline gchar const * get_stroke_style() {return stroke_style;} + + private: + StrokeStyleButtonType button_type; ///< The type (line/cap) of the button + gchar const *stroke_style; ///< The stroke style associated with the button + }; - SPObject *getMarkerName(gchar const *n, SPDocument *doc); void updateLine(); void updateAllMarkers(GSList const *objects); void updateMarkerHist(SPMarkerLoc const which); @@ -103,8 +152,16 @@ private: void setCapButtons(Gtk::ToggleButton *active); void scaleLine(); void setScaledDash(SPCSSAttr *css, int ndash, double *dash, double offset, double scale); - Gtk::RadioButton * makeRadioButton(Gtk::RadioButton *tb, char const *icon, - Gtk::HBox *hb, gchar const *key, gchar const *data); + void setMarkerColor(SPObject *marker, int loc, SPItem *item); + SPObject *forkMarker(SPObject *marker, int loc, SPItem *item); + const char *getItemColorForMarker(SPItem *item, Inkscape::PaintTarget fill_or_stroke, int loc); + + StrokeStyleButton * makeRadioButton(Gtk::RadioButtonGroup &grp, + char const *icon, + Gtk::HBox *hb, + StrokeStyleButtonType button_type, + gchar const *stroke_style); + static gboolean setStrokeWidthUnit(SPUnitSelector *, SPUnit const *old, SPUnit const *new_units, @@ -117,29 +174,30 @@ private: void miterLimitChangedCB(); void lineDashChangedCB(); static void markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMarkerLoc const which); - static void buttonToggledCB(Gtk::ToggleButton *tb, StrokeStyle *spw); + static void buttonToggledCB(StrokeStyleButton *tb, StrokeStyle *spw); MarkerComboBox *startMarkerCombo; MarkerComboBox *midMarkerCombo; MarkerComboBox *endMarkerCombo; - Gtk::Table *table; #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; GtkWidget *unitSelector; - Gtk::RadioButton *joinMiter; - Gtk::RadioButton *joinRound; - Gtk::RadioButton *joinBevel; - Gtk::RadioButton *capButt; - Gtk::RadioButton *capRound; - Gtk::RadioButton *capSquare; + StrokeStyleButton *joinMiter; + StrokeStyleButton *joinRound; + StrokeStyleButton *joinBevel; + StrokeStyleButton *capButt; + StrokeStyleButton *capRound; + StrokeStyleButton *capSquare; SPDashSelector *dashSelector; gboolean update; diff --git a/src/widgets/swatch-selector.cpp b/src/widgets/swatch-selector.cpp index 524072cf0..ad59e0dc3 100644 --- a/src/widgets/swatch-selector.cpp +++ b/src/widgets/swatch-selector.cpp @@ -1,8 +1,5 @@ - - -#include <glibmm/i18n.h> - #include "swatch-selector.h" +#include <glibmm/i18n.h> #include "document.h" #include "document-undo.h" diff --git a/src/widgets/swatch-selector.h b/src/widgets/swatch-selector.h index b97aac4f1..4b7aa483f 100644 --- a/src/widgets/swatch-selector.h +++ b/src/widgets/swatch-selector.h @@ -1,14 +1,12 @@ #ifndef SEEN_SP_SWATCH_SELECTOR_H #define SEEN_SP_SWATCH_SELECTOR_H - - #include <gtkmm/box.h> class SPDocument; class SPGradient; -class SPColorSelector; -class SPGradientSelector; +struct SPColorSelector; +struct SPGradientSelector; namespace Inkscape { diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index b769c41f6..87cb54d10 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -18,8 +18,8 @@ * * Copyright (C) 2004 David Turner * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors * Copyright (C) 2001-2002 Ximian, Inc. + * Copyright (C) 1999-2013 authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -28,10 +28,8 @@ # include "config.h" #endif - -#include <glibmm/i18n.h> - #include "ui/widget/spinbutton.h" +#include <glibmm/i18n.h> #include "toolbox.h" #include "text-toolbar.h" @@ -39,6 +37,7 @@ #include "../desktop-handles.h" #include "../desktop-style.h" #include "document-undo.h" +#include "../sp-root.h" #include "../verbs.h" #include "../inkscape.h" #include "../connection-pool.h" @@ -105,6 +104,10 @@ static void sp_print_font( SPStyle *query ) { << " FontSpec: " << (query->text->font_specification.value ? query->text->font_specification.value : "No value") << std::endl; + std::cout << " LineHeight: " << query->line_height.computed + << " WordSpacing: " << query->word_spacing.computed + << " LetterSpacing: " << query->letter_spacing.computed + << std::endl; } static void sp_print_fontweight( SPStyle *query ) { @@ -128,130 +131,7 @@ static void sp_print_fontstyle( SPStyle *query ) { } #endif -// Format family drop-down menu. -static void cell_data_func(GtkCellLayout * /*cell_layout*/, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer /*data*/) -{ - gchar *family; - gtk_tree_model_get(tree_model, iter, 0, &family, -1); - gchar *const family_escaped = g_markup_escape_text(family, -1); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int show_sample = prefs->getInt("/tools/text/show_sample_in_list", 1); - if (show_sample) { - - Glib::ustring sample = prefs->getString("/tools/text/font_sample"); - gchar *const sample_escaped = g_markup_escape_text(sample.data(), -1); - - std::stringstream markup; - markup << family_escaped << " <span foreground='gray' font_family='" - << family_escaped << "'>" << sample_escaped << "</span>"; - g_object_set (G_OBJECT (cell), "markup", markup.str().c_str(), NULL); - - g_free(sample_escaped); - } else { - g_object_set (G_OBJECT (cell), "markup", family_escaped, NULL); - } - // This doesn't work for two reasons... it set both selected and not selected backgrounds - // to white.. which means that white foreground text is invisible. It also only effects - // the text region, leaving the padding untouched. - // g_object_set (G_OBJECT (cell), "cell-background", "white", "cell-background-set", true, NULL); - - g_free(family); - g_free(family_escaped); -} - -/* - * Fill the font style combobox with the available font styles for the selected font family - * Set the selected style to that in font - */ -static void sp_text_fontstyle_populate(GObject *tbl, font_instance *font=NULL) -{ - - Ink_ComboBoxEntry_Action* act = INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); - GtkTreeModel *model = ink_comboboxentry_action_get_model( act ); - gchar *current_font = ink_comboboxentry_action_get_active_text( act ); - - // Get an iter to the selected font from the model data - // We cant get it from the combo, cause it might not have been created yet - gboolean found = false; - GtkTreeIter iter; - gboolean valid = gtk_tree_model_get_iter_first( model, &iter ); - while ( valid ) { - - // Get text from list entry - gchar* text = 0; - gtk_tree_model_get( model, &iter, 0, &text, -1 ); // Column 0 - - // Check for match - if( strcmp( current_font, text ) == 0 ){ - found = true; - break; - } - valid = gtk_tree_model_iter_next( model, &iter ); - } - - if (!found) { - return; - } - - // Get the list of styles from the selected font - GList *list=0; - gtk_tree_model_get (model, &iter, 1, &list, -1); - - Ink_ComboBoxEntry_Action* fontStyleAction = INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) ); - - gchar *current_style = ink_comboboxentry_action_get_active_text( fontStyleAction ); - - GtkListStore *store = GTK_LIST_STORE( ink_comboboxentry_action_get_model( fontStyleAction ) ); - gtk_list_store_clear ( store ); - - // Add list of styles to the style combo - for (GList *l=list; l; l = l->next) - { - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, (char*)l->data, -1); - } - - // Select the style in the combo that best matches font - if (font) { - - unsigned int index = sp_font_selector_get_best_style(font, list); - - Ink_ComboBoxEntry_Action* fontStyleAction = - INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) ); - model = ink_comboboxentry_action_get_model( fontStyleAction ); - GtkTreePath *path_c = gtk_tree_path_new (); - gtk_tree_path_append_index (path_c, index); - gtk_tree_model_get_iter(model, &iter, path_c); - gchar *name; - gtk_tree_model_get (model, &iter, 0, &name, -1); - ink_comboboxentry_action_set_active_text( fontStyleAction, name ); - - } else if (current_style) { - ink_comboboxentry_action_set_active_text( fontStyleAction, current_style ); - } - -} - // Font family -// -// In most cases we should just be able to set the new family name -// but there may be cases where a font family doesn't follow the -// standard naming pattern. To handle those cases, we do a song and -// dance to use Pango to find the best match. To do that we start -// with the old "fontSpec" (which is the returned string from -// pango_font_description_to_string() with the size unset). This -// has the form "[family-list] [style-options]" where the -// family-list is a comma separated list of font-family names -// (optionally terminated by a comma). An example would be -// "DejaVu Sans, Sans Bold". Only a "fontSpec" containing a -// single font-family will work with Pango's best match routine. -// If we can't obtain a good "fontSpec", we then resort to blindly -// changing the font-family. static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) { #ifdef DEBUG_TEXT @@ -262,156 +142,45 @@ static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GOb // 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) ); - - gchar *family = ink_comboboxentry_action_get_active_text( act ); -#ifdef DEBUG_TEXT - std::cout << " New family: " << family << std::endl; -#endif - - // First try to get the old font spec from the stored value - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); - - Glib::ustring fontSpec = query->text->font_specification.set ? query->text->font_specification.value : ""; #ifdef DEBUG_TEXT - std::cout << " fontSpec from query :" << fontSpec << ":" << std::endl; -#endif - - // If that didn't work, try to get font spec from style - if (fontSpec.empty()) { - - // Must query all to fill font-family, font-style, font-weight, font-specification - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - - // Construct a new font specification if it does not yet exist - font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query); - if( fontFromStyle ) { - fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle); - fontFromStyle->Unref(); - } - -#ifdef DEBUG_TEXT - std::cout << " fontSpec empty, try from style" << std::endl; - std::cout << " from style :" << fontSpec << ":" << std::endl; - sp_print_font( query ); -#endif - - } - - // And if that didn't work use default. DO WE REALLY WANT TO DO THIS? - if ( fontSpec.empty() ) { - - sp_style_read_from_prefs(query, "/tools/text"); - - // Construct a new font specification if it does not yet exist - font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query); - if ( fontFromStyle ) { - fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle); - fontFromStyle->Unref(); - } - -#ifdef DEBUG_TEXT - std::cout << " fontSpec empty, trying from prefs" << std::endl; - std::cout << " from prefs :" << fontSpec << ":" << std::endl; - sp_print_font( query ); + std::cout << "sp_text_fontfamily_value_changed: frozen... return" << std::endl; + std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n" << std::endl; #endif + return; } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - // Now we have a font specification, replace family. - Glib::ustring newFontSpec = ""; - SPCSSAttr *css = sp_repr_css_attr_new (); - - if (!fontSpec.empty()) newFontSpec = font_factory::Default()->ReplaceFontSpecificationFamily(fontSpec, family); - -#ifdef DEBUG_TEXT - std::cout << " New FontSpec from ReplaceFontSpecificationFamily :" << newFontSpec << ":" << std::endl; -#endif - - if (!fontSpec.empty() && !newFontSpec.empty() ) { - - if (fontSpec != newFontSpec) { - - font_instance *font = font_factory::Default()->FaceFromFontSpecification(newFontSpec.c_str()); - - if (font) { - sp_repr_css_set_property (css, "-inkscape-font-specification", newFontSpec.c_str()); - - // Set all the these just in case they were altered when finding the best - // match for the new family and old style... Unnecessary? - - gchar c[256]; - - font->Family(c, 256); - - sp_repr_css_set_property (css, "font-family", c); - - font->Attribute( "weight", c, 256); - sp_repr_css_set_property (css, "font-weight", c); - - font->Attribute("style", c, 256); - sp_repr_css_set_property (css, "font-style", c); - - font->Attribute("stretch", c, 256); - sp_repr_css_set_property (css, "font-stretch", c); - - font->Attribute("variant", c, 256); - sp_repr_css_set_property (css, "font-variant", c); - - font->Unref(); - - // Set the list of font styles - sp_text_fontstyle_populate(tbl); - - } else { - g_warning(_("Failed to find font matching: %s\n"), newFontSpec.c_str()); - } - } - } else { - - // Either old font does not exist on system or ReplaceFontSpecificationFamily() failed. - // Blindly fall back to setting the family to text in the font-family chooser. + Glib::ustring new_family = ink_comboboxentry_action_get_active_text( act ); + // TODO: Think about how to handle handle multiple selections. While + // the font-family may be the same for all, the styles might be different. + // See: TextEdit::onApply() for example of looping over selected items. + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); #ifdef DEBUG_TEXT - std::cout << " Failed to find new font, blindly setting family: " << family << std::endl; + std::cout << " Old family: " << fontlister->get_font_family() << std::endl; + std::cout << " New family: " << new_family << std::endl; + std::cout << " Old active: " << fontlister->get_font_family_row() << std::endl; + std::cout << " New active: " << act->active << std::endl; #endif - sp_repr_css_set_property (css, "-inkscape-font-specification", family); - sp_repr_css_set_property (css, "font-family", family); - } + if( new_family.compare( fontlister->get_font_family() ) != 0 ) { - // If querying returned nothing, update default style. - if (result_fontspec == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - //sp_text_edit_dialog_default_set_insensitive (); //FIXME: Replace through a verb - } - else - { - sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); - } + std::pair<Glib::ustring,Glib::ustring> ui = fontlister->set_font_family( act->active ); + // active text set in sp_text_toolbox_selection_changed() - sp_style_unref(query); + SPCSSAttr *css = sp_repr_css_attr_new (); + fontlister->fill_css( css ); - g_free (family); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css, true, true); // Results in selection change called twice. + sp_repr_css_attr_unref (css); - // Save for undo - if (result_fontspec != QUERY_STYLE_NOTHING) { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Text: Change font family")); } - sp_repr_css_attr_unref (css); // unfreeze g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); - // focus to canvas - gtk_widget_grab_focus (GTK_WIDGET((SP_ACTIVE_DESKTOP)->canvas)); - #ifdef DEBUG_TEXT std::cout << "sp_text_toolbox_fontfamily_changes: exit" << std::endl; std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" << std::endl; @@ -445,10 +214,14 @@ static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObje size = max_size; // Set css font size. - int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); SPCSSAttr *css = sp_repr_css_attr_new (); Inkscape::CSSOStringStream osfs; - osfs << size << sp_style_get_css_unit_string(unit); + int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); + if (prefs->getBool("/options/font/textOutputPx", true)) { + osfs << sp_style_css_size_units_to_px(size, unit) << sp_style_get_css_unit_string(SP_CSS_UNIT_PX); + } else { + osfs << size << sp_style_get_css_unit_string(unit); + } sp_repr_css_set_property (css, "font-size", osfs.str().c_str()); // Apply font size to selected objects. @@ -479,7 +252,6 @@ static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObje /* * Font style */ -//static void sp_text_fontstyle_value_changed( EgeSelectOneAction *act, GObject *tbl ) static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) { // quit if run by the _changed callbacks @@ -488,79 +260,26 @@ static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObj } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - // First query font-specification, this is the most complete font face description. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); - - // font_specification will not be set unless defined explicitily on a tspan. - // This should be fixed! - Glib::ustring fontSpec = query->text->font_specification.set ? query->text->font_specification.value : ""; - - if (fontSpec.empty()) { - // Construct a new font specification if it does not yet exist - // Must query font-family, font-style, font-weight, to find correct font face. - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - - font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query); - if ( fontFromStyle ) { - fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle); - fontFromStyle->Unref(); - } - } - - // Now that we have the old face, find the new face. - Glib::ustring newFontSpec = ""; - SPCSSAttr *css = sp_repr_css_attr_new (); - - gchar *current_style = ink_comboboxentry_action_get_active_text( act ); - Glib::ustring fontFamily = query->text->font_family.set ? query->text->font_family.value : ""; + Glib::ustring new_style = ink_comboboxentry_action_get_active_text( act ); - font_instance *font = (font_factory::Default())->FaceFromUIStrings (fontFamily.c_str(), current_style); + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - if (font) { - gchar c[256]; + if( new_style.compare( fontlister->get_font_style() ) != 0 ) { - font->Attribute( "weight", c, 256); - sp_repr_css_set_property (css, "font-weight", c); + fontlister->set_font_style( new_style ); + // active text set in sp_text_toolbox_seletion_changed() - font->Attribute("style", c, 256); - sp_repr_css_set_property (css, "font-style", c); + SPCSSAttr *css = sp_repr_css_attr_new (); + fontlister->fill_css( css ); - font->Attribute("stretch", c, 256); - sp_repr_css_set_property (css, "font-stretch", c); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css, true, true); + sp_repr_css_attr_unref (css); - font->Attribute("variant", c, 256); - sp_repr_css_set_property (css, "font-variant", c); - - font->Unref(); - font = NULL; - } - - - if (!newFontSpec.empty()) { - sp_repr_css_set_property (css, "-inkscape-font-specification", newFontSpec.c_str()); + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + _("Text: Change font style")); } - // If querying returned nothing, update default style. - if (result_fontspec == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } - - sp_style_unref(query); - - // Do we need to update other CSS values? - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, true); - if (result_fontspec != QUERY_STYLE_NOTHING) { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, - _("Text: Change font style")); - } - sp_repr_css_attr_unref (css); - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } @@ -659,7 +378,7 @@ 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 = sp_desktop_selection(desktop); for (GSList const *items = selection->itemList(); items != NULL; items = items->next) { - if (SP_IS_TEXT((SPItem *) items->data)) { + if (SP_IS_TEXT(SP_ITEM(items->data))) { SPItem *item = SP_ITEM(items->data); unsigned writing_mode = item->style->writing_mode.value; @@ -1081,7 +800,7 @@ static void sp_text_orientation_mode_changed( EgeSelectOneAction *act, GObject * /* * Set the default list of font sizes, scaled to the users preferred unit */ -void sp_text_set_sizes(GtkListStore* model_size, int unit) +static void sp_text_set_sizes(GtkListStore* model_size, int unit) { gtk_list_store_clear(model_size); @@ -1135,6 +854,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ if (g_object_get_data(G_OBJECT(tbl), "freeze")) { #ifdef DEBUG_TEXT std::cout << " Frozen, returning" << std::endl; + std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; std::cout << std::endl; #endif @@ -1142,6 +862,21 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + Ink_ComboBoxEntry_Action* fontFamilyAction = + INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); + Ink_ComboBoxEntry_Action* fontStyleAction = + INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) ); + + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); + fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + fontlister->selection_update(); + + // Update font list, but only if widget already created. + if( fontFamilyAction->combobox != NULL ) { + ink_comboboxentry_action_set_active_text( fontFamilyAction, fontlister->get_font_family().c_str(), fontlister->get_font_family_row() ); + ink_comboboxentry_action_set_active_text( fontStyleAction, fontlister->get_font_style().c_str() ); + } + // 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; @@ -1150,7 +885,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ items = items->next) { // const gchar* id = reinterpret_cast<SPItem *>(items->data)->getId(); // std::cout << " " << id << std::endl; - if( SP_IS_FLOWTEXT(( SPItem *) items->data )) { + if( SP_IS_FLOWTEXT(SP_ITEM(items->data))) { isFlow = true; // std::cout << " Found flowed text" << std::endl; break; @@ -1164,16 +899,12 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ * Numbers (font-size, letter-spacing, word-spacing, line-height, text-anchor, writing-mode) * Font specification (Inkscape private attribute) */ - SPStyle *query = - sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle *query = sp_style_new (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); - // Used later: - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); - /* * If no text in selection (querying returned nothing), read the style from * the /tools/text preferencess (default style for new texts). Return if @@ -1192,13 +923,18 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); #ifdef DEBUG_TEXT std::cout << " text_style_from_prefs: toolbar already set" << std:: endl; + std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; std::cout << std::endl; #endif return; } - g_object_set_data(tbl, "text_style_from_prefs", GINT_TO_POINTER(TRUE)); + // To ensure the value of the combobox is properly set on start-up, only mark + // the prefs set if the combobox has already been constructed. + if( fontFamilyAction->combobox != NULL ) { + g_object_set_data(tbl, "text_style_from_prefs", GINT_TO_POINTER(TRUE)); + } } else { g_object_set_data(tbl, "text_style_from_prefs", GINT_TO_POINTER(FALSE)); } @@ -1206,34 +942,29 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // If we have valid query data for text (font-family, font-specification) set toolbar accordingly. if (query->text) { - // Font family - if( query->text->font_family.value ) { - gchar *fontFamily = query->text->font_family.value; - - Ink_ComboBoxEntry_Action* fontFamilyAction = - INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); - ink_comboboxentry_action_set_active_text( fontFamilyAction, fontFamily ); - } - // Size (average of text selected) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); - double size = sp_style_get_css_font_size_units(query->font_size.computed, unit); + double size = sp_style_css_size_px_to_units(query->font_size.computed, unit); - gchar size_text[G_ASCII_DTOSTR_BUF_SIZE]; - g_ascii_dtostr (size_text, sizeof (size_text), size); + //gchar size_text[G_ASCII_DTOSTR_BUF_SIZE]; + //g_ascii_dtostr (size_text, sizeof (size_text), size); + + Inkscape::CSSOStringStream os; + os << size; Ink_ComboBoxEntry_Action* fontSizeAction = INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontSizeAction" ) ); + + // Freeze to ignore callbacks. + //g_object_freeze_notify( G_OBJECT( fontSizeAction->combobox ) ); sp_text_set_sizes(GTK_LIST_STORE(ink_comboboxentry_action_get_model(fontSizeAction)), unit); - ink_comboboxentry_action_set_active_text( fontSizeAction, size_text ); + //g_object_thaw_notify( G_OBJECT( fontSizeAction->combobox ) ); - Glib::ustring tooltip = Glib::ustring::format("Font size (", sp_style_get_css_unit_string(unit), ")"); - ink_comboboxentry_action_set_tooltip ( fontSizeAction, tooltip.c_str()); + ink_comboboxentry_action_set_active_text( fontSizeAction, os.str().c_str() ); - // Font styles - font_instance *font = font_factory::Default()->FaceFromStyle(query); - sp_text_fontstyle_populate(tbl, font); + Glib::ustring tooltip = Glib::ustring::format(_("Font size"), " (", sp_style_get_css_unit_string(unit), ")"); + ink_comboboxentry_action_set_tooltip ( fontSizeAction, tooltip.c_str()); // Superscript gboolean superscriptSet = @@ -1416,6 +1147,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ } #ifdef DEBUG_TEXT + std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; std::cout << std::endl; #endif @@ -1429,12 +1161,56 @@ static void sp_text_toolbox_selection_modified(Inkscape::Selection *selection, g sp_text_toolbox_selection_changed (selection, tbl); } -void +static void sp_text_toolbox_subselection_changed (gpointer /*tc*/, GObject *tbl) { sp_text_toolbox_selection_changed (NULL, tbl); } +// TODO: possibly share with font-selector by moving most code to font-lister (passing family name) +static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*position*/, GdkEvent /*event*/, gpointer /*data*/ ) { + + Glib::ustring family = gtk_entry_get_text ( entry ); + //std::cout << "text_toolbox_missing_font_cb: selecting: " << family << std::endl; + + // Get all items with matching font-family set (not inherited!). + GSList *selectList = NULL; + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *document = sp_desktop_document( desktop ); + GSList *allList = get_all_items(NULL, document->getRoot(), desktop, false, false, true, NULL); + for (GSList *i = allList; i != NULL; i = i->next) { + + SPItem *item = SP_ITEM(i->data); + SPStyle *style = item->style; + + if (style && style->text) { + + Glib::ustring family_style; + if (style->text->font_family.set) { + family_style = style->text->font_family.value; + //std::cout << " family style from font_family: " << family_style << std::endl; + } + else if (style->text->font_specification.set) { + family_style = style->text->font_specification.value; + //std::cout << " family style from font_spec: " << family_style << std::endl; + } + + if (family_style.compare( family ) == 0 ) { + //std::cout << " found: " << item->getId() << std::endl; + selectList = g_slist_prepend (selectList, item); + } + } + } + + // Update selection + Inkscape::Selection *selection = sp_desktop_selection (desktop ); + selection->clear(); + //std::cout << " list length: " << g_slist_length ( selectList ) << std::endl; + selection->setList(selectList); +} + + // Define all the "widgets" in the toolbar. void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { @@ -1449,20 +1225,33 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje /* Font family */ { // Font list - Glib::RefPtr<Gtk::ListStore> store = Inkscape::FontLister::get_instance()->get_font_list(); + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); + fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + Glib::RefPtr<Gtk::ListStore> store = fontlister->get_font_list(); GtkListStore* model = store->gobj(); - Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontFamilyAction", - _("Font Family"), - _("Select Font Family (Alt-X to access)"), - NULL, - GTK_TREE_MODEL(model), - -1, // Entry width - 50, // Extra list width - (gpointer)cell_data_func ); // Cell layout + Ink_ComboBoxEntry_Action* act = + ink_comboboxentry_action_new( "TextFontFamilyAction", + _("Font Family"), + _("Select Font Family (Alt-X to access)"), + NULL, + GTK_TREE_MODEL(model), + -1, // Entry width + 50, // Extra list width + (gpointer)font_lister_cell_data_func, // Cell layout + (gpointer)font_lister_separator_func, + GTK_WIDGET(desktop->canvas)); // Focus widget ink_comboboxentry_action_popup_enable( act ); // Enable entry completion + + gchar *const info = _("Select all text with this font-family"); + ink_comboboxentry_action_set_info( act, info ); // Show selection icon + ink_comboboxentry_action_set_info_cb( act, (gpointer)sp_text_toolbox_select_cb ); + gchar *const warning = _("Font not found on system"); - ink_comboboxentry_action_set_warning( act, warning ); // Show icon with tooltip if missing font + ink_comboboxentry_action_set_warning( act, warning ); // Show icon w/ tooltip if font missing + ink_comboboxentry_action_set_warning_cb( act, (gpointer)sp_text_toolbox_select_cb ); + + //ink_comboboxentry_action_set_warning_callback( act, sp_text_fontfamily_select_all ); ink_comboboxentry_action_set_altx_name( act, "altx-text" ); // Set Alt-X keyboard shortcut g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontfamily_value_changed), holder ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); @@ -1474,7 +1263,13 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje "{\n" " GtkComboBox::appears-as-list = 1\n" "}\n" - "widget \"*.TextFontFamilyAction_combobox\" style \"dropdown-as-list-style\""); + "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\""); } /* Font size */ @@ -1486,14 +1281,19 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje sp_text_set_sizes(model_size, unit); - Glib::ustring tooltip = Glib::ustring::format("Font size (", sp_style_get_css_unit_string(unit), ")"); + Glib::ustring tooltip = Glib::ustring::format(_("Font size"), " (", sp_style_get_css_unit_string(unit), ")"); Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontSizeAction", _("Font Size"), _(tooltip.c_str()), NULL, GTK_TREE_MODEL(model_size), - 4 ); // Width in characters + 4, // Width in characters + 0, // Extra list width + NULL, // Cell layout + NULL, // Separator + GTK_WIDGET(desktop->canvas)); // Focus widget + g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontsize_value_changed), holder ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); g_object_set_data( holder, "TextFontSizeAction", act ); @@ -1501,14 +1301,21 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje /* Font styles */ { - GtkListStore* model_style = gtk_list_store_new( 1, G_TYPE_STRING ); + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); + Glib::RefPtr<Gtk::ListStore> store = fontlister->get_style_list(); + GtkListStore* model_style = store->gobj(); - Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontStyleAction", + Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontStyleAction", _("Font Style"), _("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 + GTK_WIDGET(desktop->canvas)); // Focus widget + g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontstyle_value_changed), holder ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); g_object_set_data( holder, "TextFontStyleAction", act ); @@ -1835,17 +1642,17 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje sigc::connection *c_selection_changed = new sigc::connection (sp_desktop_selection (desktop)->connectChanged - (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_changed), (GObject*)holder))); + (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_changed), holder))); pool->add_connection ("selection-changed", c_selection_changed); sigc::connection *c_selection_modified = new sigc::connection (sp_desktop_selection (desktop)->connectModified - (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_modified), (GObject*)holder))); + (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_modified), holder))); pool->add_connection ("selection-modified", c_selection_modified); sigc::connection *c_subselection_changed = new sigc::connection (desktop->connectToolSubselectionChanged - (sigc::bind (sigc::ptr_fun (sp_text_toolbox_subselection_changed), (GObject*)holder))); + (sigc::bind (sigc::ptr_fun (sp_text_toolbox_subselection_changed), holder))); pool->add_connection ("tool-subselection-changed", c_subselection_changed); Inkscape::ConnectionPool::connect_destroy (G_OBJECT (holder), pool); diff --git a/src/widgets/text-toolbar.h b/src/widgets/text-toolbar.h index 34109c022..68158d201 100644 --- a/src/widgets/text-toolbar.h +++ b/src/widgets/text-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 49eb82de7..f03835e17 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -407,6 +407,7 @@ static gchar const * ui_descr = " <toolbar name='CalligraphyToolbar'>" " <separator />" " <toolitem action='SetProfileAction'/>" + " <toolitem action='ProfileEditAction'/>" " <separator />" " <toolitem action='CalligraphyWidthAction' />" " <toolitem action='PressureAction' />" @@ -526,7 +527,6 @@ static gchar const * ui_descr = " </toolbar>" " <toolbar name='ConnectorToolbar'>" -// " <toolitem action='ConnectorEditModeAction' />" " <toolitem action='ConnectorAvoidAction' />" " <toolitem action='ConnectorIgnoreAction' />" " <toolitem action='ConnectorOrthogonalAction' />" @@ -536,8 +536,6 @@ static gchar const * ui_descr = " <toolitem action='ConnectorLengthAction' />" " <toolitem action='ConnectorDirectedAction' />" " <toolitem action='ConnectorOverlapAction' />" -// " <toolitem action='ConnectorNewConnPointAction' />" -// " <toolitem action='ConnectorRemoveConnPointAction' />" " </toolbar>" "</ui>" @@ -938,36 +936,13 @@ static Glib::RefPtr<Gtk::ActionGroup> create_or_fetch_actions( SPDesktop* deskto } -static void handlebox_detached(GtkHandleBox* /*handlebox*/, GtkWidget* widget, gpointer /*userData*/) -{ - GtkAllocation alloc; - gtk_widget_get_allocation(widget, &alloc); - gtk_widget_set_size_request( widget, - alloc.width, - alloc.height ); -} - -static void handlebox_attached(GtkHandleBox* /*handlebox*/, GtkWidget* widget, gpointer /*userData*/) -{ - gtk_widget_set_size_request( widget, -1, -1 ); -} - -static GtkWidget* toolboxNewCommon( GtkWidget* tb, BarId id, GtkPositionType handlePos ) +static GtkWidget* toolboxNewCommon( GtkWidget* tb, BarId id, GtkPositionType /*handlePos*/ ) { g_object_set_data(G_OBJECT(tb), "desktop", NULL); gtk_widget_set_sensitive(tb, FALSE); - GtkWidget *hb = 0; - gboolean forceFloatAllowed = Inkscape::Preferences::get()->getBool("/options/workarounds/floatallowed", false); - if ( UXManager::getInstance()->isFloatWindowProblem() && !forceFloatAllowed ) { - hb = gtk_event_box_new(); // A simple, neutral container. - } else { - hb = gtk_handle_box_new(); - gtk_handle_box_set_handle_position(GTK_HANDLE_BOX(hb), handlePos); - gtk_handle_box_set_shadow_type(GTK_HANDLE_BOX(hb), GTK_SHADOW_OUT); - gtk_handle_box_set_snap_edge(GTK_HANDLE_BOX(hb), GTK_POS_LEFT); - } + GtkWidget *hb = gtk_event_box_new(); // A simple, neutral container. gtk_container_add(GTK_CONTAINER(hb), tb); gtk_widget_show(GTK_WIDGET(tb)); @@ -975,11 +950,6 @@ static GtkWidget* toolboxNewCommon( GtkWidget* tb, BarId id, GtkPositionType han sigc::connection* conn = new sigc::connection; g_object_set_data(G_OBJECT(hb), "event_context_connection", conn); - if ( GTK_IS_HANDLE_BOX(hb) ) { - g_signal_connect(G_OBJECT(hb), "child_detached", G_CALLBACK(handlebox_detached), static_cast<gpointer>(0)); - g_signal_connect(G_OBJECT(hb), "child_attached", G_CALLBACK(handlebox_attached), static_cast<gpointer>(0)); - } - gpointer val = GINT_TO_POINTER(id); g_object_set_data(G_OBJECT(hb), BAR_ID_KEY, val); @@ -1195,14 +1165,8 @@ static void setupToolboxCommon( GtkWidget *toolbox, Inkscape::IconSize toolboxSize = ToolboxFactory::prefToSize(sizePref); gtk_toolbar_set_icon_size( GTK_TOOLBAR(toolBar), static_cast<GtkIconSize>(toolboxSize) ); - if (GTK_IS_HANDLE_BOX(toolbox)) { - // g_message("GRABBING ORIENTATION [%s]", toolbarName); - GtkPositionType pos = gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(toolbox)); - orientation = ((pos == GTK_POS_LEFT) || (pos == GTK_POS_RIGHT)) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL; - } else { - GtkPositionType pos = static_cast<GtkPositionType>(GPOINTER_TO_INT(g_object_get_data( G_OBJECT(toolbox), HANDLE_POS_MARK ))); - orientation = ((pos == GTK_POS_LEFT) || (pos == GTK_POS_RIGHT)) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL; - } + GtkPositionType pos = static_cast<GtkPositionType>(GPOINTER_TO_INT(g_object_get_data( G_OBJECT(toolbox), HANDLE_POS_MARK ))); + orientation = ((pos == GTK_POS_LEFT) || (pos == GTK_POS_RIGHT)) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL; gtk_orientable_set_orientation (GTK_ORIENTABLE(toolBar), orientation); gtk_toolbar_set_show_arrow(GTK_TOOLBAR(toolBar), TRUE); @@ -1228,7 +1192,6 @@ void ToolboxFactory::setOrientation(GtkWidget* toolbox, GtkOrientation orientati #endif GtkPositionType pos = (orientation == GTK_ORIENTATION_HORIZONTAL) ? GTK_POS_LEFT : GTK_POS_TOP; - GtkHandleBox* handleBox = 0; if (GTK_IS_BIN(toolbox)) { #if DUMP_DETAILS @@ -1277,9 +1240,6 @@ void ToolboxFactory::setOrientation(GtkWidget* toolbox, GtkOrientation orientati if (GTK_IS_TOOLBAR(child2)) { GtkToolbar* childBar = GTK_TOOLBAR(child2); gtk_orientable_set_orientation(GTK_ORIENTABLE(childBar), orientation); - if (GTK_IS_HANDLE_BOX(toolbox)) { - handleBox = GTK_HANDLE_BOX(toolbox); - } } else { g_message("need to add dynamic switch"); } @@ -1287,25 +1247,14 @@ void ToolboxFactory::setOrientation(GtkWidget* toolbox, GtkOrientation orientati g_list_free(children); } else { // The call is being made before the toolbox proper has been setup. - if (GTK_IS_HANDLE_BOX(toolbox)) { - handleBox = GTK_HANDLE_BOX(toolbox); - } else { - g_object_set_data(G_OBJECT(toolbox), HANDLE_POS_MARK, GINT_TO_POINTER(pos)); - } + g_object_set_data(G_OBJECT(toolbox), HANDLE_POS_MARK, GINT_TO_POINTER(pos)); } } else if (GTK_IS_TOOLBAR(child)) { GtkToolbar* toolbar = GTK_TOOLBAR(child); gtk_orientable_set_orientation( GTK_ORIENTABLE(toolbar), orientation ); - if (GTK_IS_HANDLE_BOX(toolbox)) { - handleBox = GTK_HANDLE_BOX(toolbox); - } } } } - - if (handleBox) { - gtk_handle_box_set_handle_position(handleBox, pos); - } } void setup_tool_toolbox(GtkWidget *toolbox, SPDesktop *desktop) @@ -1423,8 +1372,13 @@ void setup_aux_toolbox(GtkWidget *toolbox, SPDesktop *desktop) GtkWidget* kludge = dataHolders[aux_toolboxes[i].type_name]; +#if GTK_CHECK_VERSION(3,0,0) + GtkWidget* holder = gtk_grid_new(); + 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 ); @@ -1438,7 +1392,12 @@ 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) ); @@ -1446,7 +1405,16 @@ void setup_aux_toolbox(GtkWidget *toolbox, SPDesktop *desktop) swatch->setClickVerb( aux_toolboxes[i].swatch_verb_id ); swatch->setWatchedTool( aux_toolboxes[i].swatch_tool, true ); GtkWidget *swatch_ = GTK_WIDGET( swatch->gobj() ); - 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, 0 ); + +#if GTK_CHECK_VERSION(3,0,0) + 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 } gtk_widget_show_all( holder ); diff --git a/src/widgets/toolbox.h b/src/widgets/toolbox.h index d520d393d..9c839a8fe 100644 --- a/src/widgets/toolbox.h +++ b/src/widgets/toolbox.h @@ -23,7 +23,7 @@ #define TOOLBAR_SLIDER_HINT "full" class SPDesktop; -class SPEventContext; +struct SPEventContext; namespace Inkscape { namespace UI { diff --git a/src/widgets/tweak-toolbar.cpp b/src/widgets/tweak-toolbar.cpp index 9b2c0bfe3..beb527a17 100644 --- a/src/widgets/tweak-toolbar.cpp +++ b/src/widgets/tweak-toolbar.cpp @@ -28,9 +28,8 @@ # include "config.h" #endif -#include <glibmm/i18n.h> - #include "ui/widget/spinbutton.h" +#include <glibmm/i18n.h> #include "toolbox.h" #include "tweak-toolbar.h" diff --git a/src/widgets/tweak-toolbar.h b/src/widgets/tweak-toolbar.h index 64608de70..6f840f2c1 100644 --- a/src/widgets/tweak-toolbar.h +++ b/src/widgets/tweak-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); diff --git a/src/widgets/widget-sizes.h b/src/widgets/widget-sizes.h index 644740637..87c7ca2e0 100644 --- a/src/widgets/widget-sizes.h +++ b/src/widgets/widget-sizes.h @@ -29,17 +29,12 @@ #define STATUS_ZOOM_WIDTH 57 -#define SELECTED_STYLE_SB_WIDTH 38 -#define SELECTED_STYLE_WIDTH 180 -#define STYLE_SWATCH_WIDTH 100 +#define SELECTED_STYLE_SB_WIDTH 48 +#define SELECTED_STYLE_WIDTH 190 +#define STYLE_SWATCH_WIDTH 135 #define STATUS_LAYER_FONT_SIZE 7700 -#define RULER_WIDTH 12 -#define RULER_HEIGHT 12 -#define RULER_FONT_SIZE 6500 -#define RULER_FONT_VERTICAL_SPACING 1.2 - /* Local Variables: mode:c++ diff --git a/src/widgets/zoom-toolbar.h b/src/widgets/zoom-toolbar.h index 9f1af4e5e..b8d6a42af 100644 --- a/src/widgets/zoom-toolbar.h +++ b/src/widgets/zoom-toolbar.h @@ -28,7 +28,7 @@ */ #include <gtk/gtk.h> -struct SPDesktop; +class SPDesktop; void sp_zoom_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); |
