static void edit_paste (GimpDisplay *display, gboolean paste_into) { GimpImage *image = gimp_display_get_image (display); gchar *svg; gsize svg_size; svg = gimp_clipboard_get_svg (display->gimp, &svg_size); if (svg) { if (gimp_vectors_import_buffer (image, svg, svg_size, TRUE, FALSE, GIMP_IMAGE_ACTIVE_PARENT, -1, NULL, NULL)) { gimp_image_flush (image); } g_free (svg); } else { GimpBuffer *buffer; buffer = gimp_clipboard_get_buffer (display->gimp); if (buffer) { GimpDisplayShell *shell = gimp_display_get_shell (display); gint x, y; gint width, height; gimp_display_shell_untransform_viewport (shell, &x, &y, &width, &height); if (gimp_edit_paste (image, gimp_image_get_active_drawable (image), buffer, paste_into, x, y, width, height)) { gimp_image_flush (image); } g_object_unref (buffer); } else { gimp_message_literal (display->gimp, G_OBJECT (display), GIMP_MESSAGE_WARNING, _("There is no image data in the clipboard to paste.")); } } }
static void quick_mask_configure_callback (GtkWidget *dialog, GimpImage *image, GimpChannel *channel, GimpContext *context, const gchar *channel_name, const GimpRGB *channel_color, gboolean save_selection, gboolean channel_visible, gboolean channel_linked, GimpColorTag channel_color_tag, gboolean channel_lock_content, gboolean channel_lock_position, gpointer user_data) { GimpRGB old_color; gimp_image_get_quick_mask_color (image, &old_color); if (gimp_rgba_distance (&old_color, channel_color) > 0.0001) { gimp_image_set_quick_mask_color (image, channel_color); gimp_image_flush (image); } gtk_widget_destroy (dialog); }
static void gimp_component_editor_clicked (GtkCellRendererToggle *cellrenderertoggle, gchar *path_str, GdkModifierType state, GimpComponentEditor *editor) { GtkTreePath *path; GtkTreeIter iter; path = gtk_tree_path_new_from_string (path_str); if (gtk_tree_model_get_iter (editor->model, &iter, path)) { GimpImage *image = GIMP_IMAGE_EDITOR (editor)->image; GimpChannelType channel; gboolean active; gtk_tree_model_get (editor->model, &iter, COLUMN_CHANNEL, &channel, -1); g_object_get (cellrenderertoggle, "active", &active, NULL); gimp_image_set_component_visible (image, channel, !active); gimp_image_flush (image); } gtk_tree_path_free (path); }
static void vectors_new_callback (GtkWidget *dialog, GimpImage *image, GimpVectors *vectors, GimpContext *context, const gchar *vectors_name, gboolean vectors_visible, gboolean vectors_linked, GimpColorTag vectors_color_tag, gboolean vectors_lock_content, gboolean vectors_lock_position, gpointer user_data) { GimpDialogConfig *config = GIMP_DIALOG_CONFIG (image->gimp->config); g_object_set (config, "path-new-name", vectors_name, NULL); vectors = gimp_vectors_new (image, config->vectors_new_name); gimp_item_set_visible (GIMP_ITEM (vectors), vectors_visible, FALSE); gimp_item_set_linked (GIMP_ITEM (vectors), vectors_linked, FALSE); gimp_item_set_color_tag (GIMP_ITEM (vectors), vectors_color_tag, FALSE); gimp_item_set_lock_content (GIMP_ITEM (vectors), vectors_lock_content, FALSE); gimp_item_set_lock_position (GIMP_ITEM (vectors), vectors_lock_position, FALSE); gimp_image_add_vectors (image, vectors, GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE); gimp_image_flush (image); gtk_widget_destroy (dialog); }
void view_use_gegl_cmd_callback (GtkAction *action, gpointer data) { GimpImage *image; GimpDisplayShell *shell; GList *layers; GList *list; gboolean active; return_if_no_image (image, data); return_if_no_shell (shell, data); active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); gimp_image_get_projection (image)->use_gegl = active; layers = gimp_image_get_layer_list (image); for (list = layers; list; list = g_list_next (list)) { GimpLayer *layer = list->data; if (GIMP_IS_GROUP_LAYER (layer)) gimp_group_layer_get_projection (GIMP_GROUP_LAYER (layer))->use_gegl = active; } g_list_free (layers); gimp_image_invalidate (image, 0, 0, gimp_image_get_width (image), gimp_image_get_height (image)); gimp_image_flush (image); }
static void select_shrink_callback (GtkWidget *widget, gdouble size, GimpUnit unit, gpointer data) { GimpImage *image = GIMP_IMAGE (data); GtkWidget *button = g_object_get_data (G_OBJECT (widget), "edge-lock-toggle"); gint radius_x; gint radius_y; radius_x = radius_y = select_shrink_pixels = ROUND (size); select_shrink_edge_lock = ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); if (unit != GIMP_UNIT_PIXEL) { gdouble factor; factor = (MAX (image->xresolution, image->yresolution) / MIN (image->xresolution, image->yresolution)); if (image->xresolution == MIN (image->xresolution, image->yresolution)) radius_y *= factor; else radius_x *= factor; } gimp_channel_shrink (gimp_image_get_mask (image), radius_x, radius_y, select_shrink_edge_lock, TRUE); gimp_image_flush (image); }
static void gimp_blend_tool_halt_preview (GimpBlendTool *blend_tool) { GimpTool *tool = GIMP_TOOL (blend_tool); if (blend_tool->graph) { g_object_unref (blend_tool->graph); blend_tool->graph = NULL; blend_tool->render_node = NULL; } if (blend_tool->image_map) { gimp_image_map_abort (blend_tool->image_map); g_object_unref (blend_tool->image_map); blend_tool->image_map = NULL; gimp_image_flush (gimp_display_get_image (tool->display)); } tool->display = NULL; tool->drawable = NULL; if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (blend_tool))) gimp_draw_tool_stop (GIMP_DRAW_TOOL (blend_tool)); }
void drawable_erode_cmd_callback (GtkAction *action, gpointer data) { GimpImage *image; GimpDrawable *drawable; GimpDisplay *display; GeglNode *node; return_if_no_drawable (image, drawable, data); return_if_no_display (display, data); node = gegl_node_new_child (NULL, "operation", "gegl:value-propagate", "mode", 1, /* GEGL_VALUE_PROPAGATE_MODE_BLACK */ "lower-threshold", 0.0, "upper-threshold", 1.0, "rate", 1.0, "top", TRUE, "left", TRUE, "right", TRUE, "bottom", TRUE, "value", TRUE, "alpha", FALSE, NULL); gimp_drawable_apply_operation (drawable, GIMP_PROGRESS (display), _("Erode"), node); g_object_unref (node); gimp_image_flush (image); }
void edit_fill_cmd_callback (GtkAction *action, gint value, gpointer data) { GimpImage *image; GimpDrawable *drawable; GimpFillType fill_type; GimpFillOptions *options; GError *error = NULL; return_if_no_drawable (image, drawable, data); fill_type = (GimpFillType) value; options = gimp_fill_options_new (action_data_get_gimp (data), NULL, FALSE); if (gimp_fill_options_set_by_fill_type (options, action_data_get_context (data), fill_type, &error)) { gimp_edit_fill (image, drawable, options, NULL); gimp_image_flush (image); } else { gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_WARNING, error->message); g_clear_error (&error); } g_object_unref (options); }
void edit_fill_cmd_callback (GtkAction *action, gint value, gpointer data) { GimpImage *image; GimpDrawable *drawable; GimpFillType fill_type; GError *error = NULL; return_if_no_drawable (image, drawable, data); fill_type = (GimpFillType) value; if (gimp_edit_fill (image, drawable, action_data_get_context (data), fill_type, GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE, &error)) { gimp_image_flush (image); } else { gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_WARNING, error->message); g_clear_error (&error); } }
static void select_feather_callback (GtkWidget *widget, gdouble size, GimpUnit unit, gpointer data) { GimpImage *image = GIMP_IMAGE (data); gdouble radius_x; gdouble radius_y; radius_x = radius_y = select_feather_radius = size; if (unit != GIMP_UNIT_PIXEL) { gdouble xres; gdouble yres; gdouble factor; gimp_image_get_resolution (image, &xres, &yres); factor = (MAX (xres, yres) / MIN (xres, yres)); if (xres == MIN (xres, yres)) radius_y *= factor; else radius_x *= factor; } gimp_channel_feather (gimp_image_get_mask (image), radius_x, radius_y, TRUE); gimp_image_flush (image); }
void select_float_cmd_callback (GtkAction *action, gpointer data) { GimpImage *image; GtkWidget *widget; GError *error = NULL; return_if_no_image (image, data); return_if_no_widget (widget, data); if (gimp_selection_float (GIMP_SELECTION (gimp_image_get_mask (image)), gimp_image_get_active_drawable (image), action_data_get_context (data), TRUE, 0, 0, &error)) { gimp_image_flush (image); } else { gimp_message_literal (image->gimp, G_OBJECT (widget), GIMP_MESSAGE_WARNING, error->message); g_clear_error (&error); } }
static void image_scale_callback (GtkWidget *dialog, GimpViewable *viewable, gint width, gint height, GimpUnit unit, GimpInterpolationType interpolation, gdouble xresolution, gdouble yresolution, GimpUnit resolution_unit, gpointer user_data) { GimpImage *image = GIMP_IMAGE (viewable); gdouble xres; gdouble yres; image_scale_unit = unit; image_scale_interp = interpolation; gimp_image_get_resolution (image, &xres, &yres); if (width > 0 && height > 0) { if (width == gimp_image_get_width (image) && height == gimp_image_get_height (image) && xresolution == xres && yresolution == yres && resolution_unit == gimp_image_get_unit (image)) return; gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_SCALE, _("Scale Image")); gimp_image_set_resolution (image, xresolution, yresolution); gimp_image_set_unit (image, resolution_unit); if (width != gimp_image_get_width (image) || height != gimp_image_get_height (image)) { GimpProgress *progress; progress = gimp_progress_start (GIMP_PROGRESS (user_data), _("Scaling"), FALSE); gimp_image_scale (image, width, height, interpolation, progress); if (progress) gimp_progress_end (progress); } gimp_image_undo_group_end (image); gimp_image_flush (image); } else { g_warning ("Scale Error: " "Both width and height must be greater than zero."); } }
static void image_print_size_callback (GtkWidget *dialog, GimpImage *image, gdouble xresolution, gdouble yresolution, GimpUnit resolution_unit, gpointer data) { gdouble xres; gdouble yres; gtk_widget_destroy (dialog); gimp_image_get_resolution (image, &xres, &yres); if (xresolution == xres && yresolution == yres && resolution_unit == gimp_image_get_unit (image)) return; gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_SCALE, _("Change Print Size")); gimp_image_set_resolution (image, xresolution, yresolution); gimp_image_set_unit (image, resolution_unit); gimp_image_undo_group_end (image); gimp_image_flush (image); }
static void gimp_drawable_tree_view_new_dropped (GimpItemTreeView *view, gint x, gint y, const GimpRGB *color, GimpPattern *pattern) { GimpItem *item; gimp_image_undo_group_start (gimp_item_tree_view_get_image (view), GIMP_UNDO_GROUP_EDIT_PASTE, _("New Layer")); item = GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->new_item (gimp_item_tree_view_get_image (view)); if (item) { gimp_edit_fill_full (gimp_item_get_image (item), GIMP_DRAWABLE (item), color, pattern, GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE, pattern ? C_("undo-type", "Drop pattern to layer") : C_("undo-type", "Drop color to layer")); } gimp_image_undo_group_end (gimp_item_tree_view_get_image (view)); gimp_image_flush (gimp_item_tree_view_get_image (view)); }
static void file_open_sanitize_image (GimpImage *image, gboolean as_new) { if (as_new) gimp_image_set_file (image, NULL); /* clear all undo steps */ gimp_image_undo_free (image); /* make sure that undo is enabled */ while (! gimp_image_undo_is_enabled (image)) gimp_image_undo_thaw (image); /* Set the image to clean. Note that export dirtiness is not set to * clean here; we can only consider export clean after the first * export */ gimp_image_clean_all (image); /* Make sure the projection is completely constructed from valid * layers, this is needed in case something triggers projection or * image preview creation before all layers are loaded, see bug #767663. */ gimp_image_invalidate (image, 0, 0, gimp_image_get_width (image), gimp_image_get_height (image)); /* Make sure all image states are up-to-date */ gimp_image_flush (image); }
static void file_open_sanitize_image (GimpImage *image, gboolean as_new) { if (as_new) gimp_image_set_uri (image, NULL); /* clear all undo steps */ gimp_image_undo_free (image); /* make sure that undo is enabled */ while (! gimp_image_undo_is_enabled (image)) gimp_image_undo_thaw (image); /* Set the image to clean. Note that export dirtiness is not set to * clean here; we can only consider export clean after the first * export */ gimp_image_clean_all (image); /* make sure the entire projection is properly constructed, because * load plug-ins are not required to call gimp_drawable_update() or * anything. */ gimp_image_invalidate (image, 0, 0, gimp_image_get_width (image), gimp_image_get_height (image)); gimp_image_flush (image); /* same for drawable previews */ gimp_image_invalidate_previews (image); }
void edit_copy_visible_cmd_callback (GtkAction *action, gpointer data) { GimpImage *image; GError *error = NULL; return_if_no_image (image, data); if (gimp_edit_copy_visible (image, action_data_get_context (data), &error)) { GimpDisplay *display = action_data_get_display (data); if (display) gimp_message_literal (image->gimp, G_OBJECT (display), GIMP_MESSAGE_INFO, _("Copied pixels to the clipboard")); gimp_image_flush (image); } else { gimp_message_literal (image->gimp, G_OBJECT (action_data_get_display (data)), GIMP_MESSAGE_WARNING, error->message); g_clear_error (&error); } }
void drawable_lock_position_cmd_callback (GtkAction *action, gpointer data) { GimpImage *image; GimpDrawable *drawable; gboolean locked; return_if_no_drawable (image, drawable, data); locked = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); if (GIMP_IS_LAYER_MASK (drawable)) drawable = GIMP_DRAWABLE (gimp_layer_mask_get_layer (GIMP_LAYER_MASK (drawable))); if (locked != gimp_item_get_lock_position (GIMP_ITEM (drawable))) { GimpUndo *undo; gboolean push_undo = TRUE; undo = gimp_image_undo_can_compress (image, GIMP_TYPE_ITEM_UNDO, GIMP_UNDO_ITEM_LOCK_POSITION); if (undo && GIMP_ITEM_UNDO (undo)->item == GIMP_ITEM (drawable)) push_undo = FALSE; gimp_item_set_lock_position (GIMP_ITEM (drawable), locked, push_undo); gimp_image_flush (image); } }
void edit_paste_as_new_layer_cmd_callback (GtkAction *action, gpointer data) { Gimp *gimp; GimpImage *image; GimpBuffer *buffer; return_if_no_gimp (gimp, data); return_if_no_image (image, data); buffer = gimp_clipboard_get_buffer (gimp); if (buffer) { GimpLayer *layer; layer = gimp_layer_new_from_buffer (gimp_buffer_get_buffer (buffer), image, gimp_image_get_layer_format (image, TRUE), _("Clipboard"), GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE); g_object_unref (buffer); gimp_image_add_layer (image, layer, GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE); gimp_image_flush (image); } else { gimp_message_literal (gimp, NULL, GIMP_MESSAGE_WARNING, _("There is no image data in the clipboard to paste.")); } }
static void select_grow_callback (GtkWidget *widget, gdouble size, GimpUnit unit, gpointer data) { GimpImage *image = GIMP_IMAGE (data); gdouble radius_x; gdouble radius_y; radius_x = radius_y = select_grow_pixels = ROUND (size); if (unit != GIMP_UNIT_PIXEL) { gdouble factor; factor = (MAX (image->xresolution, image->yresolution) / MIN (image->xresolution, image->yresolution)); if (image->xresolution == MIN (image->xresolution, image->yresolution)) radius_y *= factor; else radius_x *= factor; } gimp_channel_grow (gimp_image_get_mask (image), radius_x, radius_y, TRUE); gimp_image_flush (image); }
static void copy_named_buffer_callback (GtkWidget *widget, const gchar *name, gpointer data) { GimpImage *image = GIMP_IMAGE (data); GimpDrawable *drawable = gimp_image_get_active_drawable (image); GError *error = NULL; if (! drawable) { gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_WARNING, _("There is no active layer or channel to copy from.")); return; } if (! (name && strlen (name))) name = _("(Unnamed Buffer)"); if (gimp_edit_named_copy (image, name, drawable, gimp_get_user_context (image->gimp), &error)) { gimp_image_flush (image); } else { gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_WARNING, error->message); g_clear_error (&error); } }
/** * gimp_seamless_clone_tool_stop: * @sc: The seamless clone tool whose resources should be freed * @display_change_only: Mark that the only reason for this call was a * switch of the working display. * * This function frees any resources associated with the seamless clone * tool, including caches, gegl graphs, and anything the tool created. * Afterwards, it initializes all the relevant pointers to some initial * value (usually NULL) like the init function does. * * Note that for seamless cloning, no change needs to be done when * switching to a different display, except for clearing the image map. * So for that, we provide a boolean parameter to specify that the only * change was one of the display */ static void gimp_seamless_clone_tool_stop (GimpSeamlessCloneTool *sc, gboolean display_change_only) { /* See if we actually have any reason to stop */ if (sc->tool_state == SC_STATE_INIT) return; if (! display_change_only) { sc->tool_state = SC_STATE_INIT; g_clear_object (&sc->paste); g_clear_object (&sc->render_node); sc->sc_node = NULL; } /* This should always happen, even when we just switch a display */ if (sc->filter) { gimp_drawable_filter_abort (sc->filter); g_clear_object (&sc->filter); if (GIMP_TOOL (sc)->display) gimp_image_flush (gimp_display_get_image (GIMP_TOOL (sc)->display)); } gimp_draw_tool_stop (GIMP_DRAW_TOOL (sc)); }
void vectors_visible_cmd_callback (GtkAction *action, gpointer data) { GimpImage *image; GimpVectors *vectors; gboolean visible; return_if_no_vectors (image, vectors, data); visible = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); if (visible != gimp_item_get_visible (GIMP_ITEM (vectors))) { GimpUndo *undo; gboolean push_undo = TRUE; undo = gimp_image_undo_can_compress (image, GIMP_TYPE_ITEM_UNDO, GIMP_UNDO_ITEM_VISIBILITY); if (undo && GIMP_ITEM_UNDO (undo)->item == GIMP_ITEM (vectors)) push_undo = FALSE; gimp_item_set_visible (GIMP_ITEM (vectors), visible, push_undo); gimp_image_flush (image); } }
void vectors_paste_cmd_callback (GtkAction *action, gpointer data) { GimpImage *image; GtkWidget *widget; gchar *svg; gsize svg_size; return_if_no_image (image, data); return_if_no_widget (widget, data); svg = gimp_clipboard_get_svg (image->gimp, &svg_size); if (svg) { GError *error = NULL; if (! gimp_vectors_import_buffer (image, svg, svg_size, TRUE, FALSE, GIMP_IMAGE_ACTIVE_PARENT, -1, NULL, &error)) { gimp_message (image->gimp, G_OBJECT (widget), GIMP_MESSAGE_ERROR, "%s", error->message); g_clear_error (&error); } else { gimp_image_flush (image); } g_free (svg); } }
void vectors_linked_cmd_callback (GtkAction *action, gpointer data) { GimpImage *image; GimpVectors *vectors; gboolean linked; return_if_no_vectors (image, vectors, data); linked = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); if (linked != gimp_item_get_linked (GIMP_ITEM (vectors))) { GimpUndo *undo; gboolean push_undo = TRUE; undo = gimp_image_undo_can_compress (image, GIMP_TYPE_ITEM_UNDO, GIMP_UNDO_ITEM_LINKED); if (undo && GIMP_ITEM_UNDO (undo)->item == GIMP_ITEM (vectors)) push_undo = FALSE; gimp_item_set_linked (GIMP_ITEM (vectors), linked, push_undo); gimp_image_flush (image); } }
void vectors_select_cmd_callback (GtkAction *action, gint value, gpointer data) { GimpImage *image; GimpVectors *vectors; GimpContainer *container; GimpVectors *new_vectors; return_if_no_image (image, data); vectors = gimp_image_get_active_vectors (image); if (vectors) container = gimp_item_get_container (GIMP_ITEM (vectors)); else container = gimp_image_get_vectors (image); new_vectors = (GimpVectors *) action_select_object ((GimpActionSelectType) value, container, (GimpObject *) vectors); if (new_vectors && new_vectors != vectors) { gimp_image_set_active_vectors (image, new_vectors); gimp_image_flush (image); } }
static void vectors_import_response (GtkWidget *widget, gint response_id, VectorsImportDialog *dialog) { if (response_id == GTK_RESPONSE_OK) { gchar *filename; GError *error = NULL; vectors_import_merge = dialog->merge_vectors; vectors_import_scale = dialog->scale_vectors; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); if (gimp_vectors_import_file (dialog->image, filename, vectors_import_merge, vectors_import_scale, -1, NULL, &error)) { gimp_image_flush (dialog->image); } else { gimp_message (dialog->image->gimp, G_OBJECT (widget), GIMP_MESSAGE_ERROR, "%s", error->message); g_error_free (error); return; } g_free (filename); } gtk_widget_destroy (widget); }
static void gimp_vectors_tree_view_drop_svg (GimpContainerTreeView *tree_view, const gchar *svg_data, gsize svg_data_len, GimpViewable *dest_viewable, GtkTreeViewDropPosition drop_pos) { GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (tree_view); GimpImage *image = gimp_item_tree_view_get_image (item_view); GimpVectors *parent; gint index; GError *error = NULL; if (image->gimp->be_verbose) g_print ("%s: SVG dropped (len = %d)\n", G_STRFUNC, (gint) svg_data_len); index = gimp_item_tree_view_get_drop_index (item_view, dest_viewable, drop_pos, (GimpViewable **) &parent); if (! gimp_vectors_import_buffer (image, svg_data, svg_data_len, TRUE, FALSE, parent, index, NULL, &error)) { gimp_message_literal (image->gimp, G_OBJECT (tree_view), GIMP_MESSAGE_ERROR, error->message); g_clear_error (&error); } else { gimp_image_flush (image); } }
static void offset_response (GtkWidget *widget, gint response_id, OffsetDialog *dialog) { if (response_id == GTK_RESPONSE_OK) { GimpImage *image = dialog->image; if (image) { GimpDrawable *drawable = gimp_image_get_active_drawable (image); gint offset_x; gint offset_y; offset_x = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (dialog->off_se), 0)); offset_y = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (dialog->off_se), 1)); gimp_drawable_offset (drawable, dialog->context, dialog->fill_type & WRAP_AROUND ? TRUE : FALSE, dialog->fill_type & FILL_MASK, offset_x, offset_y); gimp_image_flush (image); } } gtk_widget_destroy (dialog->dialog); }