summaryrefslogtreecommitdiffstats
path: root/plug-ins/gfig/gfig-preview.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--plug-ins/gfig/gfig-preview.c423
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);
+ }
+}