/* PIKA - Photo and Image Kooker Application * a rebranding of The GNU Image Manipulation Program (created with heckimp) * A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio * * Original copyright, applying to most contents (license remains unchanged): * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * pikavectorstreeview.c * Copyright (C) 2001-2009 Michael Natterer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "config.h" #include #include #include #include "libpikawidgets/pikawidgets.h" #include "widgets-types.h" #include "core/pika.h" #include "core/pikacontainer.h" #include "core/pikacontext.h" #include "core/pikaimage.h" #include "vectors/pikavectors.h" #include "vectors/pikavectors-export.h" #include "vectors/pikavectors-import.h" #include "pikaactiongroup.h" #include "pikacontainerview.h" #include "pikadnd.h" #include "pikahelp-ids.h" #include "pikauimanager.h" #include "pikavectorstreeview.h" #include "pikawidgets-utils.h" #include "pika-intl.h" static void pika_vectors_tree_view_view_iface_init (PikaContainerViewInterface *iface); static void pika_vectors_tree_view_constructed (GObject *object); static void pika_vectors_tree_view_set_container (PikaContainerView *view, PikaContainer *container); static void pika_vectors_tree_view_drop_svg (PikaContainerTreeView *tree_view, const gchar *svg_data, gsize svg_data_len, PikaViewable *dest_viewable, GtkTreeViewDropPosition drop_pos); static PikaItem * pika_vectors_tree_view_item_new (PikaImage *image); static guchar * pika_vectors_tree_view_drag_svg (GtkWidget *widget, gsize *svg_data_len, gpointer data); G_DEFINE_TYPE_WITH_CODE (PikaVectorsTreeView, pika_vectors_tree_view, PIKA_TYPE_ITEM_TREE_VIEW, G_IMPLEMENT_INTERFACE (PIKA_TYPE_CONTAINER_VIEW, pika_vectors_tree_view_view_iface_init)) #define parent_class pika_vectors_tree_view_parent_class static PikaContainerViewInterface *parent_view_iface = NULL; static void pika_vectors_tree_view_class_init (PikaVectorsTreeViewClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); PikaContainerTreeViewClass *view_class = PIKA_CONTAINER_TREE_VIEW_CLASS (klass); PikaItemTreeViewClass *iv_class = PIKA_ITEM_TREE_VIEW_CLASS (klass); object_class->constructed = pika_vectors_tree_view_constructed; view_class->drop_svg = pika_vectors_tree_view_drop_svg; iv_class->item_type = PIKA_TYPE_VECTORS; iv_class->signal_name = "selected-vectors-changed"; iv_class->get_container = pika_image_get_vectors; iv_class->get_selected_items = (PikaGetItemsFunc) pika_image_get_selected_vectors; iv_class->set_selected_items = (PikaSetItemsFunc) pika_image_set_selected_vectors; iv_class->add_item = (PikaAddItemFunc) pika_image_add_vectors; iv_class->remove_item = (PikaRemoveItemFunc) pika_image_remove_vectors; iv_class->new_item = pika_vectors_tree_view_item_new; iv_class->action_group = "vectors"; iv_class->activate_action = "vectors-edit"; iv_class->new_action = "vectors-new"; iv_class->new_default_action = "vectors-new-last-values"; iv_class->raise_action = "vectors-raise"; iv_class->raise_top_action = "vectors-raise-to-top"; iv_class->lower_action = "vectors-lower"; iv_class->lower_bottom_action = "vectors-lower-to-bottom"; iv_class->duplicate_action = "vectors-duplicate"; iv_class->delete_action = "vectors-delete"; iv_class->lock_content_icon_name = PIKA_ICON_TOOL_PATH; iv_class->lock_content_tooltip = _("Lock path"); iv_class->lock_content_help_id = PIKA_HELP_PATH_LOCK_STROKES; iv_class->lock_position_icon_name = PIKA_ICON_TOOL_MOVE; iv_class->lock_position_tooltip = _("Lock path position"); iv_class->lock_position_help_id = PIKA_HELP_PATH_LOCK_POSITION; } static void pika_vectors_tree_view_view_iface_init (PikaContainerViewInterface *iface) { parent_view_iface = g_type_interface_peek_parent (iface); iface->set_container = pika_vectors_tree_view_set_container; } static void pika_vectors_tree_view_init (PikaVectorsTreeView *view) { } static void pika_vectors_tree_view_constructed (GObject *object) { PikaEditor *editor = PIKA_EDITOR (object); PikaContainerTreeView *tree_view = PIKA_CONTAINER_TREE_VIEW (object); PikaVectorsTreeView *view = PIKA_VECTORS_TREE_VIEW (object); GdkModifierType extend_mask; GdkModifierType modify_mask; G_OBJECT_CLASS (parent_class)->constructed (object); extend_mask = gtk_widget_get_modifier_mask (GTK_WIDGET (object), GDK_MODIFIER_INTENT_EXTEND_SELECTION); modify_mask = gtk_widget_get_modifier_mask (GTK_WIDGET (object), GDK_MODIFIER_INTENT_MODIFY_SELECTION); view->toselection_button = pika_editor_add_action_button (editor, "vectors", "vectors-selection-replace", "vectors-selection-add", extend_mask, "vectors-selection-subtract", modify_mask, "vectors-selection-intersect", extend_mask | modify_mask, NULL); pika_container_view_enable_dnd (PIKA_CONTAINER_VIEW (editor), GTK_BUTTON (view->toselection_button), PIKA_TYPE_VECTORS); gtk_box_reorder_child (pika_editor_get_button_box (editor), view->toselection_button, 4); view->tovectors_button = pika_editor_add_action_button (editor, "vectors", "vectors-selection-to-vectors", "vectors-selection-to-vectors-advanced", GDK_SHIFT_MASK, NULL); gtk_box_reorder_child (pika_editor_get_button_box (editor), view->tovectors_button, 5); view->stroke_button = pika_editor_add_action_button (editor, "vectors", "vectors-stroke", "vectors-stroke-last-values", GDK_SHIFT_MASK, NULL); pika_container_view_enable_dnd (PIKA_CONTAINER_VIEW (editor), GTK_BUTTON (view->stroke_button), PIKA_TYPE_VECTORS); gtk_box_reorder_child (pika_editor_get_button_box (editor), view->stroke_button, 6); pika_dnd_svg_dest_add (GTK_WIDGET (tree_view->view), NULL, view); } static void pika_vectors_tree_view_set_container (PikaContainerView *view, PikaContainer *container) { PikaContainerTreeView *tree_view = PIKA_CONTAINER_TREE_VIEW (view); PikaContainer *old_container; old_container = pika_container_view_get_container (PIKA_CONTAINER_VIEW (view)); if (old_container && ! container) { pika_dnd_svg_source_remove (GTK_WIDGET (tree_view->view)); } parent_view_iface->set_container (view, container); if (! old_container && container) { pika_dnd_svg_source_add (GTK_WIDGET (tree_view->view), pika_vectors_tree_view_drag_svg, tree_view); } } static void pika_vectors_tree_view_drop_svg (PikaContainerTreeView *tree_view, const gchar *svg_data, gsize svg_data_len, PikaViewable *dest_viewable, GtkTreeViewDropPosition drop_pos) { PikaItemTreeView *item_view = PIKA_ITEM_TREE_VIEW (tree_view); PikaImage *image = pika_item_tree_view_get_image (item_view); PikaVectors *parent; gint index; GError *error = NULL; if (image->pika->be_verbose) g_print ("%s: SVG dropped (len = %d)\n", G_STRFUNC, (gint) svg_data_len); index = pika_item_tree_view_get_drop_index (item_view, dest_viewable, drop_pos, (PikaViewable **) &parent); if (! pika_vectors_import_buffer (image, svg_data, svg_data_len, TRUE, FALSE, parent, index, NULL, &error)) { pika_message_literal (image->pika, G_OBJECT (tree_view), PIKA_MESSAGE_ERROR, error->message); g_clear_error (&error); } else { pika_image_flush (image); } } static PikaItem * pika_vectors_tree_view_item_new (PikaImage *image) { PikaVectors *new_vectors; new_vectors = pika_vectors_new (image, _("Path")); pika_image_add_vectors (image, new_vectors, PIKA_IMAGE_ACTIVE_PARENT, -1, TRUE); return PIKA_ITEM (new_vectors); } static guchar * pika_vectors_tree_view_drag_svg (GtkWidget *widget, gsize *svg_data_len, gpointer data) { PikaItemTreeView *view = PIKA_ITEM_TREE_VIEW (data); PikaImage *image = pika_item_tree_view_get_image (view); GList *items; gchar *svg_data = NULL; items = PIKA_ITEM_TREE_VIEW_GET_CLASS (view)->get_selected_items (image); *svg_data_len = 0; if (items) { svg_data = pika_vectors_export_string (image, items); if (svg_data) *svg_data_len = strlen (svg_data); } return (guchar *) svg_data; }