diff options
Diffstat (limited to 'plug-ins/gfig/gfig-preview.c')
-rw-r--r-- | plug-ins/gfig/gfig-preview.c | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/plug-ins/gfig/gfig-preview.c b/plug-ins/gfig/gfig-preview.c new file mode 100644 index 0000000..c9f0009 --- /dev/null +++ b/plug-ins/gfig/gfig-preview.c @@ -0,0 +1,423 @@ +/* + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This is a plug-in for GIMP. + * + * Generates images containing vector type drawings. + * + * Copyright (C) 1997 Andy Thomas alt@picnic.demon.co.uk + * + * 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 <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include "gfig.h" +#include "gfig-grid.h" +#include "gfig-dobject.h" +#include "gfig-preview.h" + +#include "libgimp/stdplugins-intl.h" + +#define PREVIEW_MASK (GDK_EXPOSURE_MASK | \ + GDK_POINTER_MOTION_MASK | \ + GDK_BUTTON_PRESS_MASK | \ + GDK_BUTTON_RELEASE_MASK | \ + GDK_BUTTON_MOTION_MASK | \ + GDK_KEY_PRESS_MASK | \ + GDK_KEY_RELEASE_MASK) + +static gint x_pos_val; +static gint y_pos_val; +static gint pos_tag = -1; +GtkWidget *status_label_dname; +GtkWidget *status_label_fname; +static GtkWidget *pos_label; /* XY pos marker */ + + +static void gfig_preview_realize (GtkWidget *widget); +static gboolean gfig_preview_events (GtkWidget *widget, + GdkEvent *event); +static gboolean gfig_preview_expose (GtkWidget *widget, + GdkEvent *event); + +static gint gfig_invscale_x (gint x); +static gint gfig_invscale_y (gint y); +static GtkWidget *gfig_pos_labels (void); +static GtkWidget *make_pos_info (void); + +static void gfig_pos_update (gint x, + gint y); +static void gfig_pos_update_labels (gpointer data); + +GtkWidget * +make_preview (void) +{ + GtkWidget *frame; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *table; + GtkWidget *ruler; + + gfig_context->preview = gtk_drawing_area_new (); + gtk_widget_set_events (GTK_WIDGET (gfig_context->preview), PREVIEW_MASK); + + g_signal_connect (gfig_context->preview , "realize", + G_CALLBACK (gfig_preview_realize), + NULL); + + g_signal_connect (gfig_context->preview , "event", + G_CALLBACK (gfig_preview_events), + NULL); + + g_signal_connect_after (gfig_context->preview , "expose-event", + G_CALLBACK (gfig_preview_expose), + NULL); + + gtk_widget_set_size_request (gfig_context->preview, + preview_width, preview_height); + + frame = gtk_frame_new (NULL); + + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); + + table = gtk_table_new (3, 3, FALSE); + gtk_table_attach (GTK_TABLE (table), gfig_context->preview, 1, 2, 1, 2, + GTK_FILL , GTK_FILL , 0, 0); + gtk_container_add (GTK_CONTAINER (frame), table); + + ruler = gimp_ruler_new (GTK_ORIENTATION_HORIZONTAL); + gimp_ruler_set_range (GIMP_RULER (ruler), 0, preview_width, PREVIEW_SIZE); + g_signal_connect_swapped (gfig_context->preview, "motion-notify-event", + G_CALLBACK (GTK_WIDGET_CLASS (G_OBJECT_GET_CLASS (ruler))->motion_notify_event), + ruler); + gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1, + GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (ruler); + + ruler = gimp_ruler_new (GTK_ORIENTATION_VERTICAL); + gimp_ruler_set_range (GIMP_RULER (ruler), 0, preview_height, PREVIEW_SIZE); + g_signal_connect_swapped (gfig_context->preview, "motion-notify-event", + G_CALLBACK (GTK_WIDGET_CLASS (G_OBJECT_GET_CLASS (ruler))->motion_notify_event), + ruler); + gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2, + GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (ruler); + + gtk_widget_show (frame); + gtk_widget_show (table); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + frame = make_pos_info (); + gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0); + + gtk_widget_show (vbox); + gtk_widget_show (hbox); + + return vbox; +} + +static void +gfig_preview_realize (GtkWidget *widget) +{ + GdkDisplay *display = gtk_widget_get_display (widget); + + gdk_window_set_cursor (gtk_widget_get_window (gfig_context->preview), + gdk_cursor_new_for_display (display, GDK_CROSSHAIR)); + gfig_grid_colors (widget); +} + +static void +draw_background (cairo_t *cr) +{ + if (! back_pixbuf) + back_pixbuf = gimp_image_get_thumbnail (gfig_context->image_id, + preview_width, preview_height, + GIMP_PIXBUF_LARGE_CHECKS); + + if (back_pixbuf) + { + gdk_cairo_set_source_pixbuf (cr, back_pixbuf, 0, 0); + cairo_paint (cr); + } +} + +static gboolean +gfig_preview_expose (GtkWidget *widget, + GdkEvent *event) +{ + cairo_t *cr = gdk_cairo_create (event->expose.window); + + if (gfig_context->show_background) + draw_background (cr); + + draw_grid (cr); + draw_objects (gfig_context->current_obj->obj_list, TRUE, cr); + + if (obj_creating) + { + GList *single = g_list_prepend (NULL, obj_creating); + draw_objects (single, TRUE, cr); + g_list_free (single); + } + + cairo_destroy (cr); + return FALSE; +} + +static gboolean +gfig_preview_events (GtkWidget *widget, + GdkEvent *event) +{ + GdkEventButton *bevent; + GdkEventMotion *mevent; + GdkPoint point; + static gint tmp_show_single = 0; + + switch (event->type) + { + case GDK_EXPOSE: + break; + + case GDK_BUTTON_PRESS: + bevent = (GdkEventButton *) event; + point.x = bevent->x; + point.y = bevent->y; + + g_assert (need_to_scale == 0); /* If not out of step some how */ + + /* Start drawing of object */ + if (selvals.otype >= MOVE_OBJ) + { + if (!selvals.scaletoimage) + { + point.x = gfig_invscale_x (point.x); + point.y = gfig_invscale_y (point.y); + } + object_operation_start (&point, bevent->state & GDK_SHIFT_MASK); + + /* If constraining save start pnt */ + if (selvals.opts.snap2grid) + { + /* Save point to constrained point ... if button 3 down */ + if (bevent->button == 3) + { + find_grid_pos (&point, &point, FALSE); + } + } + } + else + { + if (selvals.opts.snap2grid) + find_grid_pos (&point, &point, FALSE); + object_start (&point, bevent->state & GDK_SHIFT_MASK); + + gtk_widget_queue_draw (widget); + } + + break; + + case GDK_BUTTON_RELEASE: + bevent = (GdkEventButton *) event; + point.x = bevent->x; + point.y = bevent->y; + + if (selvals.opts.snap2grid) + find_grid_pos (&point, &point, bevent->button == 3); + + /* Still got shift down ?*/ + if (selvals.otype >= MOVE_OBJ) + { + if (!selvals.scaletoimage) + { + point.x = gfig_invscale_x (point.x); + point.y = gfig_invscale_y (point.y); + } + object_operation_end (&point, bevent->state & GDK_SHIFT_MASK); + } + else + { + if (obj_creating) + { + object_end (&point, bevent->state & GDK_SHIFT_MASK); + } + else + break; + } + + gfig_paint_callback (); + break; + + case GDK_MOTION_NOTIFY: + mevent = (GdkEventMotion *) event; + point.x = mevent->x; + point.y = mevent->y; + + if (selvals.opts.snap2grid) + find_grid_pos (&point, &point, mevent->state & GDK_BUTTON3_MASK); + + if (selvals.otype >= MOVE_OBJ) + { + /* Moving objects around */ + if (!selvals.scaletoimage) + { + point.x = gfig_invscale_x (point.x); + point.y = gfig_invscale_y (point.y); + } + object_operation (&point, mevent->state & GDK_SHIFT_MASK); + gfig_pos_update (point.x, point.y); + return FALSE; + } + + if (obj_creating) + { + obj_creating->class->update (&point); + gtk_widget_queue_draw (widget); + } + gfig_pos_update (point.x, point.y); + break; + + case GDK_KEY_PRESS: + if ((tmp_show_single = obj_show_single) != -1) + { + obj_show_single = -1; + draw_grid_clear (); + } + break; + + case GDK_KEY_RELEASE: + if (tmp_show_single != -1) + { + obj_show_single = tmp_show_single; + draw_grid_clear (); + } + break; + + default: + break; + } + + return FALSE; +} + +static GtkWidget * +make_pos_info (void) +{ + GtkWidget *frame; + GtkWidget *hbox; + GtkWidget *label; + + frame = gimp_frame_new (_("Object Details")); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE); + gtk_container_add (GTK_CONTAINER (frame), hbox); + + /* Add labels */ + label = gfig_pos_labels (); + gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); + gfig_pos_enable (NULL, NULL); + +#if 0 + label = gfig_obj_size_label (); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); +#endif /* 0 */ + + gtk_widget_show (hbox); + gtk_widget_show (frame); + + return frame; +} + +static gint +gfig_invscale_x (gint x) +{ + if (!selvals.scaletoimage) + return (gint) (x * scale_x_factor); + else + return x; +} + +static gint +gfig_invscale_y (gint y) +{ + if (!selvals.scaletoimage) + return (gint) (y * scale_y_factor); + else + return y; +} + +static GtkWidget * +gfig_pos_labels (void) +{ + GtkWidget *label; + GtkWidget *hbox; + gchar buf[256]; + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_widget_show (hbox); + + /* Position labels */ + label = gtk_label_new (_("XY position:")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + pos_label = gtk_label_new (""); + gtk_box_pack_start (GTK_BOX (hbox), pos_label, FALSE, FALSE, 0); + gtk_widget_show (pos_label); + + g_snprintf (buf, sizeof (buf), "%d, %d", 0, 0); + gtk_label_set_text (GTK_LABEL (pos_label), buf); + + return hbox; +} + +void +gfig_pos_enable (GtkWidget *widget, + gpointer data) +{ + gboolean enable = selvals.showpos; + + gtk_widget_set_sensitive (GTK_WIDGET (pos_label), enable); +} + +static void +gfig_pos_update_labels (gpointer data) +{ + static gchar buf[256]; + + pos_tag = -1; + + g_snprintf (buf, sizeof (buf), "%d, %d", x_pos_val, y_pos_val); + gtk_label_set_text (GTK_LABEL (pos_label), buf); +} + +static void +gfig_pos_update (gint x, + gint y) +{ + if ((x_pos_val !=x || y_pos_val != y) && pos_tag == -1 && selvals.showpos) + { + x_pos_val = x; + y_pos_val = y; + gfig_pos_update_labels (NULL); + } +} |