Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  gimppreview.c   Sprache: C

 

/* LIBGIMP - The GIMP Library
 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
 *
 * gimppreview.c
 *
 * This library is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
 * <https://www.gnu.org/licenses/>.
 */


#include "config.h"

#include <gegl.h>
#include <gtk/gtk.h>

#include "libgimpbase/gimpbase.h"
#include "libgimpmath/gimpmath.h"

#include "gimpwidgets.h"

#include "gimppreview.h"

#include "libgimp/libgimp-intl.h"


/**
 * SECTION: gimppreview
 * @title: GimpPreview
 * @short_description: A widget providing a #GimpPreviewArea plus
 *                     framework to update the preview.
 *
 * A widget providing a #GimpPreviewArea plus framework to update the
 * preview.
 **/



#define DEFAULT_SIZE     200
#define PREVIEW_TIMEOUT  200


enum
{
  INVALIDATED,
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_UPDATE
};


typedef struct _GimpPreviewPrivate
{
  GtkWidget *area;
  GtkWidget *grid;
  GtkWidget *frame;
  GtkWidget *toggle;
  GtkWidget *controls;
  GdkCursor *cursor_busy;
  GdkCursor *default_cursor;

  gint       xoff, yoff;
  gint       xmin, xmax, ymin, ymax;
  gint       width, height;

  gboolean   update_preview;
  guint      timeout_id;
} GimpPreviewPrivate;


static void      gimp_preview_dispose             (GObject          *object);
static void      gimp_preview_get_property        (GObject          *object,
                                                   guint             property_id,
                                                   GValue           *value,
                                                   GParamSpec       *pspec);
static void      gimp_preview_set_property        (GObject          *object,
                                                   guint             property_id,
                                                   const GValue     *value,
                                                   GParamSpec       *pspec);

static void      gimp_preview_direction_changed   (GtkWidget        *widget,
                                                   GtkTextDirection  prev_dir);
static gboolean  gimp_preview_popup_menu          (GtkWidget        *widget);

static void      gimp_preview_area_realize        (GtkWidget        *widget,
                                                   GimpPreview      *preview);
static void      gimp_preview_area_unrealize      (GtkWidget        *widget,
                                                   GimpPreview      *preview);
static void      gimp_preview_area_size_allocate  (GtkWidget        *widget,
                                                   GtkAllocation    *allocation,
                                                   GimpPreview      *preview);
static void      gimp_preview_area_set_cursor     (GimpPreview      *preview);
static gboolean  gimp_preview_area_event          (GtkWidget        *area,
                                                   GdkEvent         *event,
                                                   GimpPreview      *preview);

static void      gimp_preview_toggle_callback     (GtkWidget        *toggle,
                                                   GimpPreview      *preview);

static void      gimp_preview_notify_checks       (GimpPreview      *preview);

static gboolean  gimp_preview_invalidate_now      (GimpPreview      *preview);
static void      gimp_preview_real_set_cursor     (GimpPreview      *preview);
static void      gimp_preview_real_transform      (GimpPreview      *preview,
                                                   gint              src_x,
                                                   gint              src_y,
                                                   gint             *dest_x,
                                                   gint             *dest_y);
static void      gimp_preview_real_untransform    (GimpPreview      *preview,
                                                   gint              src_x,
                                                   gint              src_y,
                                                   gint             *dest_x,
                                                   gint             *dest_y);


G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GimpPreview, gimp_preview, GTK_TYPE_BOX)

#define parent_class gimp_preview_parent_class

static guint preview_signals[LAST_SIGNAL] = { 0 };


static void
gimp_preview_class_init (GimpPreviewClass *klass)
{
  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);

  parent_class = g_type_class_peek_parent (klass);

  preview_signals[INVALIDATED] =
    g_signal_new ("invalidated",
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GimpPreviewClass, invalidated),
                  NULL, NULL, NULL,
                  G_TYPE_NONE, 0);

  object_class->dispose           = gimp_preview_dispose;
  object_class->get_property      = gimp_preview_get_property;
  object_class->set_property      = gimp_preview_set_property;

  widget_class->direction_changed = gimp_preview_direction_changed;
  widget_class->popup_menu        = gimp_preview_popup_menu;

  klass->draw                     = NULL;
  klass->draw_thumb               = NULL;
  klass->draw_buffer              = NULL;
  klass->set_cursor               = gimp_preview_real_set_cursor;
  klass->transform                = gimp_preview_real_transform;
  klass->untransform              = gimp_preview_real_untransform;

  g_object_class_install_property (object_class,
                                   PROP_UPDATE,
                                   g_param_spec_boolean ("update",
                                                         "Update",
                                                         "Whether the preview should update automatically",
                                                         TRUE,
                                                         GIMP_PARAM_READWRITE |
                                                         G_PARAM_CONSTRUCT));

  gtk_widget_class_install_style_property (widget_class,
                                           g_param_spec_int ("size",
                                                             "Size",
                                                             "The preview's size",
                                                             1, 1024,
                                                             DEFAULT_SIZE,
                                                             GIMP_PARAM_READABLE));
}

static void
gimp_preview_init (GimpPreview *preview)
{
  GimpPreviewPrivate *priv;
  GtkWidget          *frame;
  gdouble             xalign = 0.0;

  priv = gimp_preview_get_instance_private (preview);

  gtk_orientable_set_orientation (GTK_ORIENTABLE (preview),
                                  GTK_ORIENTATION_VERTICAL);

  gtk_box_set_homogeneous (GTK_BOX (preview), FALSE);
  gtk_box_set_spacing (GTK_BOX (preview), 6);

  if (gtk_widget_get_direction (GTK_WIDGET (preview)) == GTK_TEXT_DIR_RTL)
    xalign = 1.0;

  priv->frame = gtk_aspect_frame_new (NULL, xalign, 0.0, 1.0, TRUE);
  gtk_frame_set_shadow_type (GTK_FRAME (priv->frame), GTK_SHADOW_NONE);
  gtk_box_pack_start (GTK_BOX (preview), priv->frame, TRUE, TRUE, 0);
  gtk_widget_show (priv->frame);

  priv->grid = gtk_grid_new ();
  gtk_container_add (GTK_CONTAINER (priv->frame), priv->grid);
  gtk_widget_show (priv->grid);

  priv->timeout_id = 0;

  priv->xmin   = priv->ymin = 0;
  priv->xmax   = priv->ymax = 1;
  priv->width  = priv->xmax - priv->xmin;
  priv->height = priv->ymax - priv->ymin;

  priv->xoff   = 0;
  priv->yoff   = 0;

  priv->default_cursor = NULL;

  /*  preview area  */
  frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  gtk_widget_set_hexpand (frame, TRUE);
  gtk_widget_set_vexpand (frame, TRUE);
  gtk_grid_attach (GTK_GRID (priv->grid), frame, 0, 0, 1, 1);
  gtk_widget_show (frame);

  priv->area = gimp_preview_area_new ();
  gtk_container_add (GTK_CONTAINER (frame), priv->area);
  gtk_widget_show (priv->area);

  g_signal_connect_swapped (priv->area, "notify::check-size",
                            G_CALLBACK (gimp_preview_notify_checks),
                            preview);
  g_signal_connect_swapped (priv->area, "notify::check-type",
                            G_CALLBACK (gimp_preview_notify_checks),
                            preview);
  g_signal_connect_swapped (priv->area, "notify::check-custom-color1",
                            G_CALLBACK (gimp_preview_notify_checks),
                            preview);
  g_signal_connect_swapped (priv->area, "notify::check-custom-color2",
                            G_CALLBACK (gimp_preview_notify_checks),
                            preview);

  gtk_widget_add_events (priv->area,
                         GDK_BUTTON_PRESS_MASK        |
                         GDK_BUTTON_RELEASE_MASK      |
                         GDK_SCROLL_MASK              |
                         GDK_SMOOTH_SCROLL_MASK       |
                         GDK_POINTER_MOTION_HINT_MASK |
                         GDK_BUTTON_MOTION_MASK);

  g_signal_connect (priv->area, "event",
                    G_CALLBACK (gimp_preview_area_event),
                    preview);

  g_signal_connect (priv->area, "realize",
                    G_CALLBACK (gimp_preview_area_realize),
                    preview);
  g_signal_connect (priv->area, "unrealize",
                    G_CALLBACK (gimp_preview_area_unrealize),
                    preview);

  g_signal_connect_data (priv->area, "realize",
                         G_CALLBACK (gimp_preview_area_set_cursor),
                         preview, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);

  g_signal_connect (priv->area, "size-allocate",
                    G_CALLBACK (gimp_preview_area_size_allocate),
                    preview);

  g_signal_connect_data (priv->area, "size-allocate",
                         G_CALLBACK (gimp_preview_area_set_cursor),
                         preview, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);

  priv->controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
  gtk_widget_set_margin_top (priv->controls, 3);
  gtk_grid_attach (GTK_GRID (priv->grid), priv->controls, 0, 2, 2, 1);
  gtk_widget_show (priv->controls);

  /*  toggle button to (de)activate the instant preview  */
  priv->toggle = gtk_check_button_new_with_mnemonic (_("_Preview"));
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->toggle),
                                priv->update_preview);
  gtk_box_pack_start (GTK_BOX (priv->controls), priv->toggle, TRUE, TRUE, 0);
  gtk_widget_show (priv->toggle);

  g_signal_connect (priv->toggle, "toggled",
                    G_CALLBACK (gimp_preview_toggle_callback),
                    preview);
}

static void
gimp_preview_dispose (GObject *object)
{
  GimpPreview        *preview = GIMP_PREVIEW (object);
  GimpPreviewPrivate *priv    = gimp_preview_get_instance_private (preview);

  if (priv->timeout_id)
    {
      g_source_remove (priv->timeout_id);
      priv->timeout_id = 0;
    }

  G_OBJECT_CLASS (parent_class)->dispose (object);
}

static void
gimp_preview_get_property (GObject    *object,
                           guint       property_id,
                           GValue     *value,
                           GParamSpec *pspec)
{
  GimpPreview        *preview = GIMP_PREVIEW (object);
  GimpPreviewPrivate *priv    = gimp_preview_get_instance_private (preview);

  switch (property_id)
    {
    case PROP_UPDATE:
      g_value_set_boolean (value, priv->update_preview);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

static void
gimp_preview_set_property (GObject      *object,
                           guint         property_id,
                           const GValue *value,
                           GParamSpec   *pspec)
{
  GimpPreview        *preview = GIMP_PREVIEW (object);
  GimpPreviewPrivate *priv    = gimp_preview_get_instance_private (preview);

  switch (property_id)
    {
    case PROP_UPDATE:
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->toggle),
                                    g_value_get_boolean (value));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

static void
gimp_preview_direction_changed (GtkWidget        *widget,
                                GtkTextDirection  prev_dir)
{
  GimpPreview        *preview = GIMP_PREVIEW (widget);
  GimpPreviewPrivate *priv    = gimp_preview_get_instance_private (preview);
  gdouble             xalign  = 0.0;

  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
    xalign = 1.0;

  gtk_aspect_frame_set (GTK_ASPECT_FRAME (priv->frame),
                        xalign, 0.0, 1.0, TRUE);
}

static gboolean
gimp_preview_popup_menu (GtkWidget *widget)
{
  GimpPreview        *preview = GIMP_PREVIEW (widget);
  GimpPreviewPrivate *priv    = gimp_preview_get_instance_private (preview);

  gimp_preview_area_menu_popup (GIMP_PREVIEW_AREA (priv->area), NULL);

  return TRUE;
}

static void
gimp_preview_area_realize (GtkWidget   *widget,
                           GimpPreview *preview)
{
  GimpPreviewPrivate *priv    = gimp_preview_get_instance_private (preview);
  GdkDisplay         *display = gtk_widget_get_display (widget);

  g_return_if_fail (priv->cursor_busy == NULL);

  priv->cursor_busy = gdk_cursor_new_for_display (display, GDK_WATCH);

}

static void
gimp_preview_area_unrealize (GtkWidget   *widget,
                             GimpPreview *preview)
{
  GimpPreviewPrivate *priv = gimp_preview_get_instance_private (preview);

  g_clear_object (&priv->cursor_busy);
}

static void
gimp_preview_area_size_allocate (GtkWidget     *widget,
                                 GtkAllocation *allocation,
                                 GimpPreview   *preview)
{
  GimpPreviewPrivate *priv   = gimp_preview_get_instance_private (preview);
  gint                width  = priv->xmax - priv->xmin;
  gint                height = priv->ymax - priv->ymin;

  priv->width  = MIN (width,  allocation->width);
  priv->height = MIN (height, allocation->height);

  gimp_preview_draw (preview);
  gimp_preview_invalidate (preview);
}

static void
gimp_preview_area_set_cursor (GimpPreview *preview)
{
  GIMP_PREVIEW_GET_CLASS (preview)->set_cursor (preview);
}

static gboolean
gimp_preview_area_event (GtkWidget   *area,
                         GdkEvent    *event,
                         GimpPreview *preview)
{
  GdkEventButton *button_event = (GdkEventButton *) event;

  switch (event->type)
    {
    case GDK_BUTTON_PRESS:
      switch (button_event->button)
        {
        case 3:
          gimp_preview_area_menu_popup (GIMP_PREVIEW_AREA (area), button_event);
          return TRUE;
        }
      break;

    default:
      break;
    }

  return FALSE;
}

static void
gimp_preview_toggle_callback (GtkWidget   *toggle,
                              GimpPreview *preview)
{
  GimpPreviewPrivate *priv = gimp_preview_get_instance_private (preview);

  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)))
    {
      priv->update_preview = TRUE;

      g_object_notify (G_OBJECT (preview), "update");

      if (priv->timeout_id)
        g_source_remove (priv->timeout_id);

      gimp_preview_invalidate_now (preview);
    }
  else
    {
      priv->update_preview = FALSE;

      g_object_notify (G_OBJECT (preview), "update");

      gimp_preview_draw (preview);
    }
}

static void
gimp_preview_notify_checks (GimpPreview *preview)
{
  gimp_preview_draw (preview);
  gimp_preview_invalidate (preview);
}

static gboolean
gimp_preview_invalidate_now (GimpPreview *preview)
{
  GimpPreviewPrivate *priv     = gimp_preview_get_instance_private (preview);
  GtkWidget          *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (preview));
  GimpPreviewClass   *class    = GIMP_PREVIEW_GET_CLASS (preview);

  gimp_preview_draw (preview);

  priv->timeout_id = 0;

  if (toplevel && gtk_widget_get_realized (toplevel))
    {
      gdk_window_set_cursor (gtk_widget_get_window (toplevel),
                             priv->cursor_busy);
      gdk_window_set_cursor (gtk_widget_get_window (priv->area),
                             priv->cursor_busy);

      gdk_display_flush (gtk_widget_get_display (toplevel));

      g_signal_emit (preview, preview_signals[INVALIDATED], 0);

      class->set_cursor (preview);
      gdk_window_set_cursor (gtk_widget_get_window (toplevel), NULL);
    }
  else
    {
      g_signal_emit (preview, preview_signals[INVALIDATED], 0);
    }

  return FALSE;
}

static void
gimp_preview_real_set_cursor (GimpPreview *preview)
{
  GimpPreviewPrivate *priv = gimp_preview_get_instance_private (preview);

  if (gtk_widget_get_realized (priv->area))
    gdk_window_set_cursor (gtk_widget_get_window (priv->area),
                           priv->default_cursor);
}

static void
gimp_preview_real_transform (GimpPreview *preview,
                             gint         src_x,
                             gint         src_y,
                             gint        *dest_x,
                             gint        *dest_y)
{
  GimpPreviewPrivate *priv = gimp_preview_get_instance_private (preview);

  *dest_x = src_x - priv->xoff - priv->xmin;
  *dest_y = src_y - priv->yoff - priv->ymin;
}

static void
gimp_preview_real_untransform (GimpPreview *preview,
                               gint         src_x,
                               gint         src_y,
                               gint        *dest_x,
                               gint        *dest_y)
{
  GimpPreviewPrivate *priv = gimp_preview_get_instance_private (preview);

  *dest_x = src_x + priv->xoff + priv->xmin;
  *dest_y = src_y + priv->yoff + priv->ymin;
}

/**
 * gimp_preview_set_update:
 * @preview: a #GimpPreview widget
 * @update: %TRUE if the preview should invalidate itself when being
 *          scrolled or when gimp_preview_invalidate() is being called
 *
 * Sets the state of the "Preview" check button.
 *
 * Since: 2.2
 **/

void
gimp_preview_set_update (GimpPreview *preview,
                         gboolean     update)
{
  g_return_if_fail (GIMP_IS_PREVIEW (preview));

  g_object_set (preview,
                "update", update,
                NULL);
}

/**
 * gimp_preview_get_update:
 * @preview: a #GimpPreview widget
 *
 * Returns: the state of the "Preview" check button.
 *
 * Since: 2.2
 **/

gboolean
gimp_preview_get_update (GimpPreview *preview)
{
  GimpPreviewPrivate *priv;

  g_return_val_if_fail (GIMP_IS_PREVIEW (preview), FALSE);

  priv = gimp_preview_get_instance_private (preview);

  return priv->update_preview;
}

/**
 * gimp_preview_set_bounds:
 * @preview: a #GimpPreview widget
 * @xmin:    the minimum X value
 * @ymin:    the minimum Y value
 * @xmax:    the maximum X value
 * @ymax:    the maximum Y value
 *
 * Sets the lower and upper limits for the previewed area. The
 * difference between the upper and lower value is used to set the
 * maximum size of the #GimpPreviewArea used in the @preview.
 *
 * Since: 2.2
 **/

void
gimp_preview_set_bounds (GimpPreview *preview,
                         gint         xmin,
                         gint         ymin,
                         gint         xmax,
                         gint         ymax)
{
  GimpPreviewPrivate *priv;

  g_return_if_fail (GIMP_IS_PREVIEW (preview));
  g_return_if_fail (xmax > xmin);
  g_return_if_fail (ymax > ymin);

  priv = gimp_preview_get_instance_private (preview);

  priv->xmin = xmin;
  priv->ymin = ymin;
  priv->xmax = xmax;
  priv->ymax = ymax;

  gimp_preview_area_set_max_size (GIMP_PREVIEW_AREA (priv->area),
                                  xmax - xmin,
                                  ymax - ymin);
}

/**
 * gimp_preview_get_bounds:
 * @preview: A #GimpPreview:
 * @xmin: (out) (optional): Lower bound for x
 * @ymin: (out) (optional): Lower bound for y
 * @xmax: (out) (optional): Higher bound for x
 * @ymax: (out) (optional): Higher bound for y
 */

void
gimp_preview_get_bounds (GimpPreview *preview,
                         gint        *xmin,
                         gint        *ymin,
                         gint        *xmax,
                         gint        *ymax)
{
  GimpPreviewPrivate *priv;

  g_return_if_fail (GIMP_IS_PREVIEW (preview));

  priv = gimp_preview_get_instance_private (preview);

  if (xmin) *xmin = priv->xmin;
  if (ymin) *ymin = priv->ymin;
  if (xmax) *xmax = priv->xmax;
  if (ymax) *ymax = priv->ymax;
}

void
gimp_preview_set_size (GimpPreview *preview,
                       gint         width,
                       gint         height)
{
  GimpPreviewPrivate *priv;

  g_return_if_fail (GIMP_IS_PREVIEW (preview));

  priv = gimp_preview_get_instance_private (preview);

  priv->width  = width;
  priv->height = height;

  gtk_widget_set_size_request (priv->area, width, height);
}

/**
 * gimp_preview_get_size:
 * @preview: a #GimpPreview widget
 * @width: (out) (optional): return location for the preview area width
 * @height: (out) (optional): return location for the preview area height
 *
 * Since: 2.2
 **/

void
gimp_preview_get_size (GimpPreview *preview,
                       gint        *width,
                       gint        *height)
{
  GimpPreviewPrivate *priv;

  g_return_if_fail (GIMP_IS_PREVIEW (preview));

  priv = gimp_preview_get_instance_private (preview);

  if (width)  *width  = priv->width;
  if (height) *height = priv->height;
}

void
gimp_preview_set_offsets (GimpPreview *preview,
                          gint         xoff,
                          gint         yoff)
{
  GimpPreviewPrivate *priv;

  g_return_if_fail (GIMP_IS_PREVIEW (preview));

  priv = gimp_preview_get_instance_private (preview);

  priv->xoff = xoff;
  priv->yoff = yoff;
}

/**
 * gimp_preview_get_offsets:
 * @preview: A #GimpPreview:
 * @xoff: (out) (optional): X offset
 * @yoff: (out) (optional): Y offset
 */

void
gimp_preview_get_offsets (GimpPreview *preview,
                          gint        *xoff,
                          gint        *yoff)
{
  GimpPreviewPrivate *priv;

  g_return_if_fail (GIMP_IS_PREVIEW (preview));

  priv = gimp_preview_get_instance_private (preview);

  if (xoff) *xoff = priv->xoff;
  if (yoff) *yoff = priv->yoff;
}

/**
 * gimp_preview_get_position:
 * @preview: a #GimpPreview widget
 * @x: (out) (optional): return location for the horizontal offset
 * @y: (out) (optional): return location for the vertical offset
 *
 * Since: 2.2
 **/

void
gimp_preview_get_position (GimpPreview *preview,
                           gint        *x,
                           gint        *y)
{
  GimpPreviewPrivate *priv;

  g_return_if_fail (GIMP_IS_PREVIEW (preview));

  priv = gimp_preview_get_instance_private (preview);

  if (x) *x = priv->xoff + priv->xmin;
  if (y) *y = priv->yoff + priv->ymin;
}

/**
 * gimp_preview_transform:
 * @preview: a #GimpPreview widget
 * @src_x:   horizontal position on the previewed image
 * @src_y:   vertical position on the previewed image
 * @dest_x: (out): returns the transformed horizontal position
 * @dest_y: (out): returns the transformed vertical position
 *
 * Transforms from image to widget coordinates.
 *
 * Since: 2.4
 **/

void
gimp_preview_transform (GimpPreview *preview,
                        gint         src_x,
                        gint         src_y,
                        gint        *dest_x,
                        gint        *dest_y)
{
  g_return_if_fail (GIMP_IS_PREVIEW (preview));
  g_return_if_fail (dest_x != NULL && dest_y != NULL);

  GIMP_PREVIEW_GET_CLASS (preview)->transform (preview,
                                               src_x, src_y, dest_x, dest_y);
}

/**
 * gimp_preview_untransform:
 * @preview: a #GimpPreview widget
 * @src_x:   horizontal position relative to the preview area's origin
 * @src_y:   vertical position relative to  preview area's origin
 * @dest_x: (out): returns the untransformed horizontal position
 * @dest_y: (out): returns the untransformed vertical position
 *
 * Transforms from widget to image coordinates.
 *
 * Since: 2.4
 **/

void
gimp_preview_untransform (GimpPreview *preview,
                          gint         src_x,
                          gint         src_y,
                          gint        *dest_x,
                          gint        *dest_y)
{
  g_return_if_fail (GIMP_IS_PREVIEW (preview));
  g_return_if_fail (dest_x != NULL && dest_y != NULL);

  GIMP_PREVIEW_GET_CLASS (preview)->untransform (preview,
                                                 src_x, src_y, dest_x, dest_y);
}

/**
 * gimp_preview_get_frame:
 * @preview: a #GimpPreview widget
 *
 * Returns: (transfer none) (type GtkAspectFrame): a pointer to the
 * #GtkAspectFrame used in the @preview.
 *
 * Since: 3.0
 **/

GtkWidget *
gimp_preview_get_frame (GimpPreview  *preview)
{
  GimpPreviewPrivate *priv;

  g_return_val_if_fail (GIMP_IS_PREVIEW (preview), NULL);

  priv = gimp_preview_get_instance_private (preview);

  return priv->frame;
}

/**
 * gimp_preview_get_grid:
 * @preview: a #GimpPreview widget
 *
 * Returns: (transfer none) (type GtkGrid): a pointer to
 * the #GtkGrid used in the @preview.
 *
 * Since: 3.0
 **/

GtkWidget *
gimp_preview_get_grid (GimpPreview  *preview)
{
  GimpPreviewPrivate *priv;

  g_return_val_if_fail (GIMP_IS_PREVIEW (preview), NULL);

  priv = gimp_preview_get_instance_private (preview);

  return priv->grid;
}

/**
 * gimp_preview_get_area:
 * @preview: a #GimpPreview widget
 *
 * In most cases, you shouldn't need to access the #GimpPreviewArea
 * that is being used in the @preview. Sometimes however, you need to.
 * For example if you want to receive mouse events from the area. In
 * such cases, use gimp_preview_get_area().
 *
 * Returns: (transfer none) (type GimpPreviewArea): a pointer to the
 * #GimpPreviewArea used in the @preview.
 *
 * Since: 2.4
 **/

GtkWidget *
gimp_preview_get_area (GimpPreview  *preview)
{
  GimpPreviewPrivate *priv;

  g_return_val_if_fail (GIMP_IS_PREVIEW (preview), NULL);

  priv = gimp_preview_get_instance_private (preview);

  return priv->area;
}

/**
 * gimp_preview_draw:
 * @preview: a #GimpPreview widget
 *
 * Calls the GimpPreview::draw method. GimpPreview itself doesn't
 * implement a default draw method so the behavior is determined by
 * the derived class implementing this method.
 *
 * #GimpDrawablePreview implements gimp_preview_draw() by drawing the
 * original, unmodified drawable to the @preview.
 *
 * Since: 2.2
 **/

void
gimp_preview_draw (GimpPreview *preview)
{
  GimpPreviewClass *class = GIMP_PREVIEW_GET_CLASS (preview);

  if (class->draw)
    class->draw (preview);
}

/**
 * gimp_preview_draw_buffer:
 * @preview:   a #GimpPreview widget
 * @buffer: (array): a pixel buffer the size of the preview
 * @rowstride: the @buffer's rowstride
 *
 * Calls the GimpPreview::draw_buffer method. GimpPreview itself
 * doesn't implement this method so the behavior is determined by the
 * derived class implementing this method.
 *
 * Since: 2.2
 **/

void
gimp_preview_draw_buffer (GimpPreview  *preview,
                          const guchar *buffer,
                          gint          rowstride)
{
  GimpPreviewClass *class = GIMP_PREVIEW_GET_CLASS (preview);

  if (class->draw_buffer)
    class->draw_buffer (preview, buffer, rowstride);
}

/**
 * gimp_preview_invalidate:
 * @preview: a #GimpPreview widget
 *
 * This function starts or renews a short low-priority timeout. When
 * the timeout expires, the GimpPreview::invalidated signal is emitted
 * which will usually cause the @preview to be updated.
 *
 * This function does nothing unless the "Preview" button is checked.
 *
 * During the emission of the signal a busy cursor is set on the
 * toplevel window containing the @preview and on the preview area
 * itself.
 *
 * Since: 2.2
 **/

void
gimp_preview_invalidate (GimpPreview *preview)
{
  GimpPreviewPrivate *priv;

  g_return_if_fail (GIMP_IS_PREVIEW (preview));

  priv = gimp_preview_get_instance_private (preview);

  if (priv->update_preview)
    {
      if (priv->timeout_id)
        g_source_remove (priv->timeout_id);

      priv->timeout_id =
        g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, PREVIEW_TIMEOUT,
                            (GSourceFunc) gimp_preview_invalidate_now,
                            preview, NULL);
    }
}

/**
 * gimp_preview_set_default_cursor:
 * @preview: a #GimpPreview widget
 * @cursor:  a #GdkCursor or %NULL
 *
 * Sets the default mouse cursor for the preview.  Note that this will
 * be overridden by a %GDK_FLEUR if the preview has scrollbars, or by a
 * %GDK_WATCH when the preview is invalidated.
 *
 * Since: 2.2
 **/

void
gimp_preview_set_default_cursor (GimpPreview *preview,
                                 GdkCursor   *cursor)
{
  GimpPreviewPrivate *priv;

  g_return_if_fail (GIMP_IS_PREVIEW (preview));

  priv = gimp_preview_get_instance_private (preview);

  g_set_object (&priv->default_cursor, cursor);
}

/**
 * gimp_preview_get_default_cursor:
 * @preview: a #GimpPreview widget
 *
 * See gimp_preview_set_default_cursor():
 *
 * Returns: (transfer none): The @preview's default #GdkCursor.
 *
 * Since: 3.0
 **/

GdkCursor *
gimp_preview_get_default_cursor (GimpPreview *preview)
{
  GimpPreviewPrivate *priv;

  g_return_val_if_fail (GIMP_IS_PREVIEW (preview), NULL);

  priv = gimp_preview_get_instance_private (preview);

  return priv->default_cursor;
}

/**
 * gimp_preview_get_controls:
 * @preview: a #GimpPreview widget
 *
 * Gives access to the horizontal #GtkBox at the bottom of the preview
 * that contains the update toggle. Derived widgets can use this function
 * if they need to add controls to this area.
 *
 * Returns: (transfer none) (type GtkBox): the horizontal #GtkBox at the
 * bottom of the preview.
 *
 * Since: 2.4
 **/

GtkWidget *
gimp_preview_get_controls (GimpPreview *preview)
{
  GimpPreviewPrivate *priv;

  g_return_val_if_fail (GIMP_IS_PREVIEW (preview), NULL);

  priv = gimp_preview_get_instance_private (preview);

  return priv->controls;
}

Messung
CHZG
811009692

¤ Dauer der Verarbeitung: 0.6 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104838
#Domains=499075