X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Finterface.cpp;h=1ad90c58c5746f1dfde172fc477b812407357fd3;hb=144c1b594591ba3d62513b126ca87a5f242b2f2b;hp=f43c31d301b9725cf955a76176bce70002f68afe;hpb=ceadd9a0b7904f7628a04f4fcf628feea517637c;p=inkscape.git diff --git a/src/interface.cpp b/src/interface.cpp index f43c31d30..1ad90c58c 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -39,7 +39,10 @@ #include "svg-view-widget.h" #include "widgets/desktop-widget.h" #include "sp-item-group.h" +#include "sp-text.h" +#include "sp-flowtext.h" #include "sp-namedview.h" +#include "ui/view/view.h" #include "helper/action.h" #include "helper/gnome-utils.h" @@ -62,16 +65,17 @@ #include "svg/svg-color.h" #include "desktop-style.h" #include "style.h" +#include "event-context.h" +#include "gradient-drag.h" +// Include Mac OS X menu synchronization on native OSX build +#ifdef GDK_WINDOWING_QUARTZ +#include "ige-mac-menu.h" +#endif using Inkscape::IO::StringOutputStream; using Inkscape::IO::Base64OutputStream; -/* forward declaration */ -static gint sp_ui_delete(GtkWidget *widget, GdkEvent *event, Inkscape::UI::View::View *view); -static void sp_ui_state_event(GtkWidget *widget, GdkEventWindowState *event, SPDesktop*desktop); - - /* Drag and Drop */ typedef enum { URI_LIST, @@ -85,15 +89,15 @@ typedef enum { } ui_drop_target_info; static GtkTargetEntry ui_drop_target_entries [] = { - {"text/uri-list", 0, URI_LIST}, - {"image/svg+xml", 0, SVG_XML_DATA}, - {"image/svg", 0, SVG_DATA}, - {"image/png", 0, PNG_DATA}, - {"image/jpeg", 0, JPEG_DATA}, + {(gchar *)"text/uri-list", 0, URI_LIST }, + {(gchar *)"image/svg+xml", 0, SVG_XML_DATA }, + {(gchar *)"image/svg", 0, SVG_DATA }, + {(gchar *)"image/png", 0, PNG_DATA }, + {(gchar *)"image/jpeg", 0, JPEG_DATA }, #if ENABLE_MAGIC_COLORS - {"application/x-inkscape-color", 0, APP_X_INKY_COLOR}, + {(gchar *)"application/x-inkscape-color", 0, APP_X_INKY_COLOR}, #endif // ENABLE_MAGIC_COLORS - {"application/x-color", 0, APP_X_COLOR} + {(gchar *)"application/x-color", 0, APP_X_COLOR } }; static GtkTargetEntry *completeDropTargets = 0; @@ -111,6 +115,17 @@ static void sp_ui_drag_data_received(GtkWidget *widget, guint info, guint event_time, gpointer user_data); +static void sp_ui_drag_motion( GtkWidget *widget, + GdkDragContext *drag_context, + gint x, gint y, + GtkSelectionData *data, + guint info, + guint event_time, + gpointer user_data ); +static void sp_ui_drag_leave( GtkWidget *widget, + GdkDragContext *drag_context, + guint event_time, + gpointer user_data ); static void sp_ui_menu_item_set_sensitive(SPAction *action, unsigned int sensitive, void *data); @@ -135,26 +150,23 @@ sp_create_window(SPViewWidget *vw, gboolean editable) g_return_if_fail(vw != NULL); g_return_if_fail(SP_IS_VIEW_WIDGET(vw)); - GtkWidget *win = sp_window_new("", TRUE); + Gtk::Window *win = Inkscape::UI::window_new("", TRUE); if (editable) { - g_object_set_data(G_OBJECT(vw), "window", win); - reinterpret_cast(vw)->window = - static_cast((void*)win); - } - - if (editable) { - SPDesktop* desktop = SP_DESKTOP_WIDGET(vw)->desktop; - - /* fixme: doesn't allow making window any smaller than this */ - gtk_window_set_default_size((GtkWindow *) win, 640, 480); - g_object_set_data(G_OBJECT(win), "desktop", desktop); - g_object_set_data(G_OBJECT(win), "desktopwidget", vw); - g_signal_connect(G_OBJECT(win), "delete_event", G_CALLBACK(sp_ui_delete), vw->view); - - g_signal_connect(G_OBJECT(win), "window_state_event", G_CALLBACK(sp_ui_state_event), static_cast(vw->view)); - g_signal_connect(G_OBJECT(win), "focus_in_event", G_CALLBACK(sp_desktop_widget_set_focus), vw); - + g_object_set_data(G_OBJECT(vw), "window", win); + + SPDesktopWidget *desktop_widget = reinterpret_cast(vw); + SPDesktop* desktop = desktop_widget->desktop; + + desktop_widget->window = win; + + win->set_data("desktop", desktop); + win->set_data("desktopwidget", desktop_widget); + + win->signal_delete_event().connect(sigc::mem_fun(*(SPDesktop*)vw->view, &SPDesktop::onDeleteUI)); + win->signal_window_state_event().connect(sigc::mem_fun(*desktop, &SPDesktop::onWindowStateEvent)); + win->signal_focus_in_event().connect(sigc::mem_fun(*desktop_widget, &SPDesktopWidget::onFocusInEvent)); + gint prefs_geometry = (2==prefs_get_int_attribute("options.savewindowgeometry", "value", 0)); if (prefs_geometry) { @@ -191,18 +203,18 @@ sp_create_window(SPViewWidget *vw, gboolean editable) } } if (maxed) { - gtk_window_maximize(GTK_WINDOW(win)); + win->maximize(); } if (full) { - gtk_window_fullscreen(GTK_WINDOW(win)); + win->fullscreen(); } } } else { - gtk_window_set_policy(GTK_WINDOW(win), TRUE, TRUE, TRUE); + gtk_window_set_policy(GTK_WINDOW(win->gobj()), TRUE, TRUE, TRUE); } - gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(vw)); + gtk_container_add(GTK_CONTAINER(win->gobj()), GTK_WIDGET(vw)); gtk_widget_show(GTK_WIDGET(vw)); if ( completeDropTargets == 0 || completeDropTargetsCount == 0 ) @@ -236,16 +248,26 @@ sp_create_window(SPViewWidget *vw, gboolean editable) } } - gtk_drag_dest_set(win, + gtk_drag_dest_set((GtkWidget*)win->gobj(), GTK_DEST_DEFAULT_ALL, completeDropTargets, completeDropTargetsCount, GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE)); - g_signal_connect(G_OBJECT(win), + + + g_signal_connect(G_OBJECT(win->gobj()), "drag_data_received", G_CALLBACK(sp_ui_drag_data_received), NULL); - gtk_widget_show(win); + g_signal_connect(G_OBJECT(win->gobj()), + "drag_motion", + G_CALLBACK(sp_ui_drag_motion), + NULL); + g_signal_connect(G_OBJECT(win->gobj()), + "drag_leave", + G_CALLBACK(sp_ui_drag_leave), + NULL); + win->show(); // needed because the first ACTIVATE_DESKTOP was sent when there was no window yet inkscape_reactivate_desktop(SP_DESKTOP_WIDGET(vw)->desktop); @@ -290,7 +312,7 @@ sp_ui_new_view_preview() * \param widget unused */ void -sp_ui_close_view(GtkWidget *widget) +sp_ui_close_view(GtkWidget */*widget*/) { if (SP_ACTIVE_DESKTOP == NULL) { return; @@ -329,59 +351,6 @@ sp_ui_close_all(void) return TRUE; } -static gint -sp_ui_delete(GtkWidget *widget, GdkEvent *event, Inkscape::UI::View::View *view) -{ - return view->shutdown(); -} - -/** - * sp_ui_state_event - * - * Called when the window changes its maximize/fullscreen/iconify/pinned state. - * Since GTK doesn't have a way to query this state information directly, we - * record it for the desktop here, and also possibly trigger a layout. - */ -static void -sp_ui_state_event(GtkWidget *widget, GdkEventWindowState *event, SPDesktop* desktop) -{ - // Record the desktop window's state - desktop->window_state = event->new_window_state; - - // Layout may differ depending on full-screen mode or not - GdkWindowState changed = event->changed_mask; - if (changed & (GDK_WINDOW_STATE_FULLSCREEN|GDK_WINDOW_STATE_MAXIMIZED)) { - desktop->layoutWidget(); - } -/* - // debug info - g_message("State event desktop=0x%p", desktop); - GdkWindowState state = event->new_window_state; - GdkWindowState changed = event->changed_mask; - if (changed & GDK_WINDOW_STATE_WITHDRAWN) { - g_message("-- WIDTHDRAWN = %d", 0!=(state&GDK_WINDOW_STATE_WITHDRAWN)); - } - if (changed & GDK_WINDOW_STATE_ICONIFIED) { - g_message("-- ICONIFIED = %d", 0!=(state&GDK_WINDOW_STATE_ICONIFIED)); - } - if (changed & GDK_WINDOW_STATE_MAXIMIZED) { - g_message("-- MAXIMIZED = %d", 0!=(state&GDK_WINDOW_STATE_MAXIMIZED)); - } - if (changed & GDK_WINDOW_STATE_STICKY) { - g_message("-- STICKY = %d", 0!=(state&GDK_WINDOW_STATE_STICKY)); - } - if (changed & GDK_WINDOW_STATE_FULLSCREEN) { - g_message("-- FULLSCREEN = %d", 0!=(state&GDK_WINDOW_STATE_FULLSCREEN)); - } - if (changed & GDK_WINDOW_STATE_ABOVE) { - g_message("-- ABOVE = %d", 0!=(state&GDK_WINDOW_STATE_ABOVE)); - } - if (changed & GDK_WINDOW_STATE_BELOW) { - g_message("-- BELOW = %d", 0!=(state&GDK_WINDOW_STATE_BELOW)); - } -*/ -} - /* * Some day when the right-click menus are ready to start working * smarter with the verbs, we'll need to change this NULL being @@ -390,19 +359,19 @@ sp_ui_state_event(GtkWidget *widget, GdkEventWindowState *event, SPDesktop* desk * investigate when they're called. */ static void -sp_ui_menu_activate(void *object, SPAction *action) +sp_ui_menu_activate(void */*object*/, SPAction *action) { sp_action_perform(action, NULL); } static void -sp_ui_menu_select_action(void *object, SPAction *action) +sp_ui_menu_select_action(void */*object*/, SPAction *action) { action->view->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, action->tip); } static void -sp_ui_menu_deselect_action(void *object, SPAction *action) +sp_ui_menu_deselect_action(void */*object*/, SPAction *action) { action->view->tipsMessageContext()->clear(); } @@ -500,9 +469,10 @@ sp_key_name(guint keyval) else if (!strcmp(n, "Page_Down" )) return "PgDn"; else if (!strcmp(n, "grave" )) return "`"; else if (!strcmp(n, "numbersign" )) return "#"; - else if (!strcmp(n, "bar" )) return "|"; - else if (!strcmp(n, "slash" )) return "/"; - else if (!strcmp(n, "exclam" )) return "!"; + else if (!strcmp(n, "bar" )) return "|"; + else if (!strcmp(n, "slash" )) return "/"; + else if (!strcmp(n, "exclam" )) return "!"; + else if (!strcmp(n, "percent" )) return "%"; else return n; } @@ -676,7 +646,7 @@ checkitem_toggled(GtkCheckMenuItem *menuitem, gpointer user_data) } static gboolean -checkitem_update(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) +checkitem_update(GtkWidget *widget, GdkEventExpose */*event*/, gpointer user_data) { GtkCheckMenuItem *menuitem=GTK_CHECK_MENU_ITEM(widget); @@ -763,13 +733,13 @@ sp_ui_menu_append_check_item_from_verb(GtkMenu *menu, Inkscape::UI::View::View * } static void -sp_recent_open(GtkWidget *widget, gchar const *uri) +sp_recent_open(GtkWidget */*widget*/, gchar const *uri) { sp_file_open(uri, NULL); } static void -sp_file_new_from_template(GtkWidget *widget, gchar const *uri) +sp_file_new_from_template(GtkWidget */*widget*/, gchar const *uri) { sp_file_new(uri); } @@ -977,9 +947,17 @@ sp_ui_main_menubar(Inkscape::UI::View::View *view) { GtkWidget *mbar = gtk_menu_bar_new(); +#ifdef GDK_WINDOWING_QUARTZ + ige_mac_menu_set_menu_bar(GTK_MENU_SHELL(mbar)); +#endif + sp_ui_build_dyn_menus(inkscape_get_menus(INKSCAPE), mbar, view); +#ifdef GDK_WINDOWING_QUARTZ + return NULL; +#else return mbar; +#endif } static void leave_group(GtkMenuItem *, SPDesktop *desktop) { @@ -1071,8 +1049,8 @@ sp_ui_drag_data_received(GtkWidget *widget, gint x, gint y, GtkSelectionData *data, guint info, - guint event_time, - gpointer user_data) + guint /*event_time*/, + gpointer /*user_data*/) { SPDocument *doc = SP_ACTIVE_DOCUMENT; SPDesktop *desktop = SP_ACTIVE_DESKTOP; @@ -1089,13 +1067,15 @@ sp_ui_drag_data_received(GtkWidget *widget, SPItem *item = desktop->item_at_point( where, true ); if ( item ) { + bool fillnotstroke = (drag_context->action != GDK_ACTION_MOVE); + if ( data->length >= 8 ) { cmsHPROFILE srgbProf = cmsCreate_sRGBProfile(); gchar c[64] = {0}; // Careful about endian issues. guint16* dataVals = (guint16*)data->data; - sp_svg_write_color( c, 64, + sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( 0x0ff & (dataVals[0] >> 8), 0x0ff & (dataVals[1] >> 8), @@ -1124,18 +1104,18 @@ sp_ui_drag_data_received(GtkWidget *widget, str = 0; sp_object_setAttribute( SP_OBJECT(item), - (drag_context->action != GDK_ACTION_MOVE) ? "inkscape:x-fill-tag":"inkscape:x-stroke-tag", + fillnotstroke ? "inkscape:x-fill-tag":"inkscape:x-stroke-tag", palName.c_str(), false ); item->updateRepr(); - sp_repr_css_set_property( css, (drag_context->action != GDK_ACTION_MOVE) ? "fill":"stroke", c ); + sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", c ); updatePerformed = true; } } if ( !updatePerformed ) { - sp_repr_css_set_property( css, (drag_context->action != GDK_ACTION_MOVE) ? "fill":"stroke", c ); + sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", c ); } sp_desktop_apply_css_recursive( item, css, true ); @@ -1159,24 +1139,69 @@ sp_ui_drag_data_received(GtkWidget *widget, int destY = 0; gtk_widget_translate_coordinates( widget, &(desktop->canvas->widget), x, y, &destX, &destY ); NR::Point where( sp_canvas_window_to_world( desktop->canvas, NR::Point( destX, destY ) ) ); + NR::Point const button_dt(desktop->w2d(where)); + NR::Point const button_doc(desktop->dt2doc(button_dt)); + + if ( data->length == 8 ) { + gchar c[64] = {0}; + // Careful about endian issues. + guint16* dataVals = (guint16*)data->data; + sp_svg_write_color( c, 64, + SP_RGBA32_U_COMPOSE( + 0x0ff & (dataVals[0] >> 8), + 0x0ff & (dataVals[1] >> 8), + 0x0ff & (dataVals[2] >> 8), + 0xff // can't have transparency in the color itself + //0x0ff & (data->data[3] >> 8), + )); + + SPItem *item = desktop->item_at_point( where, true ); + + bool consumed = false; + if (desktop->event_context && desktop->event_context->get_drag()) { + consumed = desktop->event_context->get_drag()->dropColor(item, c, button_dt); + if (consumed) { + sp_document_done( doc , SP_VERB_NONE, _("Drop color on gradient")); + desktop->event_context->get_drag()->updateDraggers(); + } + } + + //if (!consumed && tools_active(desktop, TOOLS_TEXT)) { + // consumed = sp_text_context_drop_color(c, button_doc); + // if (consumed) { + // sp_document_done( doc , SP_VERB_NONE, _("Drop color on gradient stop")); + // } + //} + + if (!consumed && item) { + bool fillnotstroke = (drag_context->action != GDK_ACTION_MOVE); + if (fillnotstroke && + (SP_IS_SHAPE(item) || SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item))) { + Path *livarot_path = Path_for_item(item, true, true); + livarot_path->ConvertWithBackData(0.04); + + NR::Maybe position = get_nearest_position_on_Path(livarot_path, button_doc); + if (position) { + NR::Point nearest = get_point_on_Path(livarot_path, position->piece, position->t); + NR::Point delta = nearest - button_doc; + delta = desktop->d2w(delta); + double stroke_tolerance = + ( !SP_OBJECT_STYLE(item)->stroke.isNone() ? + desktop->current_zoom() * + SP_OBJECT_STYLE (item)->stroke_width.computed * + NR::expansion(from_2geom(sp_item_i2d_affine(item))) * 0.5 + : 0.0) + + prefs_get_int_attribute_limited("options.dragtolerance", "value", 0, 0, 100); + + if (NR::L2 (delta) < stroke_tolerance) { + fillnotstroke = false; + } + } + delete livarot_path; + } - SPItem *item = desktop->item_at_point( where, true ); - if ( item ) - { - if ( data->length == 8 ) { - gchar c[64] = {0}; - // Careful about endian issues. - guint16* dataVals = (guint16*)data->data; - sp_svg_write_color( c, 64, - SP_RGBA32_U_COMPOSE( - 0x0ff & (dataVals[0] >> 8), - 0x0ff & (dataVals[1] >> 8), - 0x0ff & (dataVals[2] >> 8), - 0xff // can't have transparency in the color itself - //0x0ff & (data->data[3] >> 8), - )); SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property( css, (drag_context->action != GDK_ACTION_MOVE) ? "fill":"stroke", c ); + sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", c ); sp_desktop_apply_css_recursive( item, css, true ); item->updateRepr(); @@ -1301,6 +1326,31 @@ sp_ui_drag_data_received(GtkWidget *widget, } } +#include "gradient-context.h" + +void sp_ui_drag_motion( GtkWidget */*widget*/, + GdkDragContext */*drag_context*/, + gint /*x*/, gint /*y*/, + GtkSelectionData */*data*/, + guint /*info*/, + guint /*event_time*/, + gpointer /*user_data*/) +{ +// SPDocument *doc = SP_ACTIVE_DOCUMENT; +// SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + +// g_message("drag-n-drop motion (%4d, %4d) at %d", x, y, event_time); +} + +static void sp_ui_drag_leave( GtkWidget */*widget*/, + GdkDragContext */*drag_context*/, + guint /*event_time*/, + gpointer /*user_data*/ ) +{ +// g_message("drag-n-drop leave at %d", event_time); +} + static void sp_ui_import_files(gchar *buffer) { @@ -1313,7 +1363,7 @@ sp_ui_import_files(gchar *buffer) } static void -sp_ui_import_one_file_with_check(gpointer filename, gpointer unused) +sp_ui_import_one_file_with_check(gpointer filename, gpointer /*unused*/) { if (filename) { if (strlen((char const *)filename) > 2) @@ -1355,15 +1405,10 @@ sp_ui_overwrite_file(gchar const *filename) bool return_value = FALSE; if (Inkscape::IO::file_test(filename, G_FILE_TEST_EXISTS)) { - GtkWidget* ancestor = 0; - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - desktop->getToplevel( ancestor ); - } - GtkWindow *window = GTK_WIDGET_TOPLEVEL(ancestor) ? GTK_WINDOW( ancestor ) : 0; + Gtk::Window *window = SP_ACTIVE_DESKTOP->getToplevel(); gchar* baseName = g_path_get_basename( filename ); gchar* dirName = g_path_get_dirname( filename ); - GtkWidget* dialog = gtk_message_dialog_new_with_markup( window, + GtkWidget* dialog = gtk_message_dialog_new_with_markup( window->gobj(), (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, @@ -1394,13 +1439,13 @@ sp_ui_overwrite_file(gchar const *filename) } static void -sp_ui_menu_item_set_sensitive(SPAction *action, unsigned int sensitive, void *data) +sp_ui_menu_item_set_sensitive(SPAction */*action*/, unsigned int sensitive, void *data) { return gtk_widget_set_sensitive(GTK_WIDGET(data), sensitive); } static void -sp_ui_menu_item_set_name(SPAction *action, Glib::ustring name, void *data) +sp_ui_menu_item_set_name(SPAction */*action*/, Glib::ustring name, void *data) { void *child = GTK_BIN (data)->child; //child is either