static gboolean
draw_cb (GtkDrawingArea *drawing_area,
		 cairo_t *cr,
		 gpointer  user_data)
{
	update_relative_sizes (PHOTOS_PRINT_PREVIEW (user_data));

	photos_print_preview_draw (PHOTOS_PRINT_PREVIEW (user_data), cr);

	if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
		fprintf (stderr, "Cairo is unhappy: %s\n",
			 cairo_status_to_string (cairo_status (cr)));
	}

	return TRUE;
}
static gboolean
button_press_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
  PhotosPrintPreview *preview = PHOTOS_PRINT_PREVIEW (user_data);

  preview->priv->cursorx = event->x;
  preview->priv->cursory = event->y;

  switch (event->button)
    {
    case 1:
      preview->priv->grabbed = press_inside_image_area (preview, event->x, event->y);
      break;

    default:
      break;
    }

  if (preview->priv->grabbed)
    {
      gtk_widget_queue_draw (GTK_WIDGET (preview));
    }

  gtk_widget_grab_focus (preview->priv->area);

  return FALSE;
}
Ejemplo n.º 3
0
static gboolean
on_preview_image_key_pressed (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
    PhotosPrintSetupPrivate *priv = PHOTOS_PRINT_SETUP (user_data)->priv;
    PhotosPrintPreview *preview = PHOTOS_PRINT_PREVIEW (widget);
    gfloat scale;

    scale = photos_print_preview_get_scale (preview);

    switch (event->keyval)
    {
    case GDK_KEY_KP_Add:
    case GDK_KEY_plus:
        /* scale up */
        scale *= 1.1;
        break;
    case GDK_KEY_KP_Subtract:
    case GDK_KEY_minus:
        /* scale down */
        scale *= 0.9;
        break;
    default:
        return FALSE;
        break;
    }

    gtk_range_set_value (GTK_RANGE (priv->scaling), 100*scale);

    return TRUE;
}
Ejemplo n.º 4
0
static gboolean
on_preview_image_scrolled (GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
{
    PhotosPrintSetup *self = PHOTOS_PRINT_SETUP (user_data);
    PhotosPrintSetupPrivate *priv = self->priv;
    PhotosPrintPreview *preview = PHOTOS_PRINT_PREVIEW (widget);
    gfloat scale;

    scale = photos_print_preview_get_scale (preview);

    if (!photos_print_preview_point_in_image_area (preview, event->x, event->y))
        return FALSE;

    switch (event->direction)
    {
    case GDK_SCROLL_UP:
        /* scale up */
        scale *= 1.1;
        break;
    case GDK_SCROLL_DOWN:
        /* scale down */
        scale *= 0.9;
        break;
    case GDK_SCROLL_LEFT:
    case GDK_SCROLL_RIGHT:
    case GDK_SCROLL_SMOOTH:
    default:
        return FALSE;
        break;
    }

    gtk_range_set_value (GTK_RANGE (priv->scaling), 100*scale);

    return TRUE;
}
Ejemplo n.º 5
0
static void
photos_print_setup_position_values_changed (PhotosPrintSetup *self,
        GtkWidget *w_changed,
        GtkWidget *w_to_update,
        GtkWidget *w_size,
        gdouble total_size,
        gint change)
{
    PhotosPrintSetupPrivate *priv = self->priv;
    gdouble changed, to_update, size;
    gdouble pos;

    size = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w_size));
    changed = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w_changed));

    to_update = total_size - changed - size;
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (w_to_update), to_update);
    gtk_combo_box_set_active (GTK_COMBO_BOX (priv->center), CENTER_NONE);

    switch (change)
    {
    case CHANGE_HORIZ:
        pos = gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->left));
        if (priv->current_unit == GTK_UNIT_MM)
            pos *= FACTOR_MM_TO_INCH;
        photos_print_preview_set_image_position (PHOTOS_PRINT_PREVIEW (priv->preview), pos, -1);
        break;
    case CHANGE_VERT:
        pos = gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->top));
        if (priv->current_unit == GTK_UNIT_MM)
            pos *= FACTOR_MM_TO_INCH;
        photos_print_preview_set_image_position (PHOTOS_PRINT_PREVIEW (priv->preview), -1, pos);
        break;
    default:
        g_assert_not_reached ();
        break;
    }
}
/**
 * photos_print_preview_new_with_pixbuf:
 * @pixbuf: a #GdkPixbuf
 *
 * Creates a new #PhotosPrintPreview widget, and sets the #GdkPixbuf to preview
 * on it.
 *
 * Returns: A new #PhotosPrintPreview widget.
 **/
GtkWidget *
photos_print_preview_new_with_pixbuf (GdkPixbuf *pixbuf)
{
	PhotosPrintPreview *preview;

	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);

	preview = PHOTOS_PRINT_PREVIEW (photos_print_preview_new ());

	preview->priv->pixbuf = g_object_ref (pixbuf);

	update_relative_sizes (preview);

	return GTK_WIDGET (preview);
}
Ejemplo n.º 7
0
static void
photos_print_setup_set_initial_values (PhotosPrintSetup *self)
{
    PhotosPrintSetupPrivate *priv = self->priv;
    GeglRectangle bbox;
    gdouble page_height;
    gdouble page_width;
    gdouble factor;
    gdouble height;
    gdouble max_perc;
    gdouble width;

    factor = get_scale_to_px_factor (self);

    bbox = gegl_node_get_bounding_box (priv->node);
    width = (gdouble) bbox.width/factor;
    height = (gdouble) bbox.height/factor;

    max_perc = photos_print_setup_get_max_percentage (self);

    width *= max_perc;
    height *= max_perc;

    gtk_range_set_range (GTK_RANGE (priv->scaling), 1, 100 * max_perc);
    gtk_range_set_increments (GTK_RANGE (priv->scaling), max_perc, 10 * max_perc);
    gtk_range_set_value (GTK_RANGE (priv->scaling), 100 * max_perc);

    photos_print_preview_set_scale (PHOTOS_PRINT_PREVIEW (priv->preview), max_perc);
    gtk_spin_button_set_range (GTK_SPIN_BUTTON (priv->width), 0, width);
    gtk_spin_button_set_range (GTK_SPIN_BUTTON (priv->height), 0, height);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->width), width);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->height), height);

    gtk_combo_box_set_active (GTK_COMBO_BOX (priv->center), CENTER_BOTH);

    photos_print_setup_center (gtk_page_setup_get_page_width (priv->page_setup, priv->current_unit),
                               gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->width)),
                               GTK_SPIN_BUTTON (priv->left), GTK_SPIN_BUTTON (priv->right));
    photos_print_setup_center (gtk_page_setup_get_page_height (priv->page_setup, priv->current_unit),
                               gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->height)),
                               GTK_SPIN_BUTTON (priv->top), GTK_SPIN_BUTTON (priv->bottom));

    page_width = gtk_page_setup_get_page_width (priv->page_setup, priv->current_unit);
    page_height = gtk_page_setup_get_page_height (priv->page_setup, priv->current_unit);

    update_image_pos_ranges (self, page_width, page_height, width, height);
}
static void
size_allocate_cb (GtkWidget *widget, GtkAllocation *allocation, gpointer user_data)
{
  PhotosPrintPreview *preview;

  preview = PHOTOS_PRINT_PREVIEW (user_data);
  update_relative_sizes (preview);

  preview->priv->flag_create_surface = TRUE;

  if (preview->priv->pixbuf_scaled != NULL)
    {
      g_object_unref (preview->priv->pixbuf_scaled);
      preview->priv->pixbuf_scaled = NULL;
    }

  g_idle_add ((GSourceFunc) create_surface_when_idle, preview);
}
Ejemplo n.º 9
0
static void
on_scale_changed (GtkRange *range, gpointer user_data)
{
    PhotosPrintSetup *self = PHOTOS_PRINT_SETUP (user_data);
    PhotosPrintSetupPrivate *priv = self->priv;
    GeglRectangle bbox;
    gdouble height;
    gdouble scale;
    gdouble width;
    gdouble left, right, top, bottom;
    gdouble page_width, page_height;
    gdouble factor;

    gtk_combo_box_set_active (GTK_COMBO_BOX (priv->center), CENTER_NONE);

    bbox = gegl_node_get_bounding_box (priv->node);
    factor = get_scale_to_px_factor (self);

    width = (gdouble) bbox.width / factor;
    height = (gdouble) bbox.height / factor;

    left = gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->left));
    top = gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->top));

    scale = CLAMP (0.01 * gtk_range_get_value (range), 0, photos_print_setup_get_max_percentage (self));

    photos_print_preview_set_scale (PHOTOS_PRINT_PREVIEW (priv->preview), scale);

    width  *= scale;
    height *= scale;

    page_width = gtk_page_setup_get_page_width (priv->page_setup, priv->current_unit);
    page_height = gtk_page_setup_get_page_height (priv->page_setup, priv->current_unit);

    update_image_pos_ranges (self, page_width, page_height, width, height);

    right = page_width - left - width;
    bottom = page_height - top - height;

    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->width), width);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->height), height);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->right), right);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->bottom), bottom);
}
static void
photos_print_preview_get_property (GObject    *object,
				guint       prop_id,
				GValue     *value,
				GParamSpec *pspec)
{
	PhotosPrintPreviewPrivate *priv = PHOTOS_PRINT_PREVIEW (object)->priv;

	switch (prop_id) {
	case PROP_PIXBUF:
		g_value_set_object (value, priv->pixbuf);
		break;
	case PROP_PIXBUF_X_ALIGN:
		g_value_set_float (value, priv->pixbuf_x_align);
		break;
	case PROP_PIXBUF_Y_ALIGN:
		g_value_set_float (value, priv->pixbuf_y_align);
		break;
	case PROP_PIXBUF_SCALE:
		g_value_set_float (value, priv->i_scale);
		break;
	case PROP_PAPER_WIDTH:
		g_value_set_float (value, priv->p_width);
		break;
	case PROP_PAPER_HEIGHT:
		g_value_set_float (value, priv->p_height);
		break;
	case PROP_PAGE_LEFT_MARGIN:
		g_value_set_float (value, priv->l_margin);
		break;
	case PROP_PAGE_RIGHT_MARGIN:
		g_value_set_float (value, priv->r_margin);
		break;
	case PROP_PAGE_TOP_MARGIN:
		g_value_set_float (value, priv->t_margin);
		break;
	case PROP_PAGE_BOTTOM_MARGIN:
		g_value_set_float (value, priv->b_margin);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
	}
}
static gboolean
button_release_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
  PhotosPrintPreview *preview = PHOTOS_PRINT_PREVIEW (user_data);

  switch (event->button)
    {
    case 1:
      preview->priv->grabbed = FALSE;
      preview->priv->r_dx = 0;
      preview->priv->r_dy = 0;
      gtk_widget_queue_draw (GTK_WIDGET (preview));
      break;

    default:
      break;
    }

  return FALSE;
}
Ejemplo n.º 12
0
static void
photos_print_setup_constructed (GObject *object)
{
    PhotosPrintSetup *self = PHOTOS_PRINT_SETUP (object);
    PhotosPrintSetupPrivate *priv = self->priv;

    G_OBJECT_CLASS (photos_print_setup_parent_class)->constructed (object);

    photos_print_setup_set_initial_values (self);
    photos_print_preview_set_from_page_setup (PHOTOS_PRINT_PREVIEW (priv->preview), priv->page_setup);

    g_signal_connect (priv->left, "value-changed", G_CALLBACK (on_left_value_changed), self);
    g_signal_connect (priv->right, "value-changed", G_CALLBACK (on_right_value_changed), self);
    g_signal_connect (priv->top, "value-changed", G_CALLBACK (on_top_value_changed), self);
    g_signal_connect (priv->bottom, "value-changed", G_CALLBACK (on_bottom_value_changed), self);
    g_signal_connect (priv->width, "value-changed", G_CALLBACK (on_width_value_changed), self);
    g_signal_connect (priv->height, "value-changed", G_CALLBACK (on_height_value_changed), self);
    g_signal_connect (priv->scaling, "value-changed", G_CALLBACK (on_scale_changed), self);
    g_signal_connect (priv->scaling, "format-value", G_CALLBACK (on_scale_format_value), NULL);
    g_signal_connect (priv->preview, "pixbuf-moved", G_CALLBACK (on_preview_pixbuf_moved), self);
    g_signal_connect (priv->preview, "scroll-event", G_CALLBACK (on_preview_image_scrolled), self);
    g_signal_connect (priv->preview, "key-press-event", G_CALLBACK (on_preview_image_key_pressed), self);
}
static void
photos_print_preview_finalize (GObject *object)
{
	PhotosPrintPreviewPrivate *priv;

	priv = PHOTOS_PRINT_PREVIEW (object)->priv;

	if (priv->pixbuf) {
		g_object_unref (priv->pixbuf);
		priv->pixbuf = NULL;
	}

	if (priv->pixbuf_scaled) {
		g_object_unref (priv->pixbuf_scaled);
		priv->pixbuf_scaled = NULL;
	}

	if (priv->surface) {
		cairo_surface_destroy (priv->surface);
		priv->surface = NULL;
	}

	G_OBJECT_CLASS (photos_print_preview_parent_class)->finalize (object);
}
static gboolean
motion_notify_event_cb (GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
{
  PhotosPrintPreviewPrivate *priv = PHOTOS_PRINT_PREVIEW (user_data)->priv;
  GtkAllocation allocation;
  gdouble dx, dy;

  if (priv->grabbed)
    {
      dx = event->x - priv->cursorx;
      dy = event->y - priv->cursory;

      gtk_widget_get_allocation (widget, &allocation);

      /* Make sure the image stays inside the margins */

      priv->pixbuf_x_align += (dx + priv->r_dx) / (allocation.width  - priv->r_width - priv->l_rmargin - priv->r_rmargin);
      if (priv->pixbuf_x_align < 0. || priv->pixbuf_x_align > 1.)
        {
          priv->pixbuf_x_align = CLAMP (priv->pixbuf_x_align, 0., 1.);
          priv->r_dx += dx;
        }
      else
        priv->r_dx = 0;

      priv->pixbuf_y_align += (dy + priv->r_dy) / (allocation.height - priv->r_height - priv->t_rmargin - priv->b_rmargin);
      if (priv->pixbuf_y_align < 0. || priv->pixbuf_y_align > 1.)
        {
          priv->pixbuf_y_align = CLAMP (priv->pixbuf_y_align, 0., 1.);
          priv->r_dy += dy;
        }
      else
        priv->r_dy = 0;

      /* we do this to correctly change the property values */
      g_object_set (PHOTOS_PRINT_PREVIEW (user_data),
                    "pixbuf-x-align", priv->pixbuf_x_align,
                    "pixbuf-y-align", priv->pixbuf_y_align,
                    NULL);

      priv->cursorx = event->x;
      priv->cursory = event->y;

      g_signal_emit (G_OBJECT (user_data), preview_signals[SIGNAL_PIXBUF_MOVED], 0);
    }
  else
    {
      if (press_inside_image_area (PHOTOS_PRINT_PREVIEW (user_data), event->x, event->y))
        {
          GdkCursor *cursor;
          cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), GDK_FLEUR);
          gdk_window_set_cursor (gtk_widget_get_window (widget), cursor);
          g_object_unref (cursor);
        }
      else
        {
          gdk_window_set_cursor (gtk_widget_get_window (widget), NULL);
        }
    }

  return FALSE;
}
static void
photos_print_preview_set_property (GObject      *object,
				guint         prop_id,
				const GValue *value,
				GParamSpec   *pspec)
{
	PhotosPrintPreviewPrivate *priv = PHOTOS_PRINT_PREVIEW (object)->priv;
	gboolean paper_size_changed = FALSE;

	switch (prop_id) {
	case PROP_PIXBUF:
		if (priv->pixbuf) {
			g_object_unref (priv->pixbuf);
		}
		priv->pixbuf = GDK_PIXBUF (g_value_dup_object (value));

		if (priv->pixbuf_scaled) {
			g_object_unref (priv->pixbuf_scaled);
			priv->pixbuf_scaled = NULL;
		}

		priv->flag_create_surface = TRUE;
		break;
	case PROP_PIXBUF_X_ALIGN:
		priv->pixbuf_x_align = g_value_get_float (value);
		break;
	case PROP_PIXBUF_Y_ALIGN:
		priv->pixbuf_y_align = g_value_get_float (value);
		break;
	case PROP_PIXBUF_SCALE:
		priv->i_scale = g_value_get_float (value);
		priv->flag_create_surface = TRUE;
		break;
	case PROP_PAPER_WIDTH:
		priv->p_width = g_value_get_float (value);
		paper_size_changed = TRUE;
		break;
	case PROP_PAPER_HEIGHT:
		priv->p_height = g_value_get_float (value);
		paper_size_changed = TRUE;
		break;
	case PROP_PAGE_LEFT_MARGIN:
		priv->l_margin = g_value_get_float (value);
		break;
	case PROP_PAGE_RIGHT_MARGIN:
		priv->r_margin = g_value_get_float (value);
		break;
	case PROP_PAGE_TOP_MARGIN:
		priv->t_margin = g_value_get_float (value);
		break;
	case PROP_PAGE_BOTTOM_MARGIN:
		priv->b_margin = g_value_get_float (value);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
	}

	if (paper_size_changed) {
		g_object_set (object,
			      "ratio", priv->p_width/priv->p_height,
			      NULL);
	}

	update_relative_sizes (PHOTOS_PRINT_PREVIEW (object));
	gtk_widget_queue_draw (priv->area);
}
Ejemplo n.º 16
0
static void
photos_print_setup_size_changed (PhotosPrintSetup *self,
                                 GtkWidget *w_size_x,
                                 GtkWidget *w_size_y,
                                 GtkWidget *w_margin_x_1,
                                 GtkWidget *w_margin_x_2,
                                 GtkWidget *w_margin_y_1,
                                 GtkWidget *w_margin_y_2,
                                 gdouble page_size_x,
                                 gdouble page_size_y,
                                 gint change)
{
    PhotosPrintSetupPrivate *priv = self->priv;
    GeglRectangle bbox;
    gdouble margin_x_1, margin_x_2;
    gdouble margin_y_1, margin_y_2;
    gdouble orig_size_x = -1, orig_size_y = -1, scale;
    gdouble size_x, size_y;
    gdouble factor;

    size_x = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w_size_x));
    margin_x_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w_margin_x_1));
    margin_y_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w_margin_y_1));

    bbox = gegl_node_get_bounding_box (priv->node);
    factor = get_scale_to_px_factor (self);

    switch (change)
    {
    case CHANGE_HORIZ:
        orig_size_x = (gdouble) bbox.width / factor;
        orig_size_y = (gdouble) bbox.height / factor;
        break;
    case CHANGE_VERT:
        orig_size_y = (gdouble) bbox.width / factor;
        orig_size_x = (gdouble) bbox.height / factor;
        break;
    default:
        g_assert_not_reached ();
        break;
    }

    scale = CLAMP (size_x / orig_size_x, 0, 1);

    size_y = scale * orig_size_y;

    margin_x_2 = page_size_x - margin_x_1 - size_x;
    margin_y_2 = page_size_y - margin_y_1 - size_y;

    photos_print_preview_set_scale (PHOTOS_PRINT_PREVIEW (priv->preview), scale);

    switch (change)
    {
    case CHANGE_HORIZ:
        update_image_pos_ranges (self, page_size_x, page_size_y, size_x, size_y);
        break;
    case CHANGE_VERT:
        update_image_pos_ranges (self, page_size_y, page_size_x, size_y, size_x);
        break;
    default:
        g_assert_not_reached ();
        break;
    }

    gtk_range_set_value (GTK_RANGE (priv->scaling), 100*scale);

    gtk_spin_button_set_value (GTK_SPIN_BUTTON (w_margin_x_2), margin_x_2);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (w_size_y), size_y);
    gtk_spin_button_set_value (GTK_SPIN_BUTTON (w_margin_y_2), margin_y_2);

    gtk_combo_box_set_active (GTK_COMBO_BOX (priv->center), CENTER_NONE);
}