/**
 * gimp_display_shell_rotate_xy:
 * @shell:
 * @x:
 * @y:
 * @nx:
 * @ny:
 *
 * Rotates an unrotated display coordinate to a rotated shell coordinate.
 **/
void
gimp_display_shell_rotate_xy (const GimpDisplayShell *shell,
                              gdouble                 x,
                              gdouble                 y,
                              gint                   *nx,
                              gint                   *ny)
{
  gint64 tx;
  gint64 ty;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
  g_return_if_fail (nx != NULL);
  g_return_if_fail (ny != NULL);

  if (shell->rotate_transform)
    cairo_matrix_transform_point (shell->rotate_transform, &x, &y);

  tx = x;
  ty = y;

  /*  The projected coordinates might overflow a gint in the case of
   *  big images at high zoom levels, so we clamp them here to avoid
   *  problems.
   */
  *nx = CLAMP (tx, G_MININT, G_MAXINT);
  *ny = CLAMP (ty, G_MININT, G_MAXINT);
}
/**
 * gimp_display_shell_scroll_set_offsets:
 * @shell:
 * @offset_x:
 * @offset_y:
 *
 * This function scrolls the image in the shell's viewport. It redraws
 * the entire canvas.
 *
 * Use it for setting the scroll offset on freshly scaled images or
 * when the window is resized. For panning, use
 * gimp_display_shell_scroll().
 **/
void
gimp_display_shell_scroll_set_offset (GimpDisplayShell *shell,
                                      gint              offset_x,
                                      gint              offset_y)
{
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  if (shell->offset_x == offset_x &&
      shell->offset_y == offset_y)
    return;

  gimp_display_shell_scale_save_revert_values (shell);

  /* freeze the active tool */
  gimp_display_shell_pause (shell);

  shell->offset_x = offset_x;
  shell->offset_y = offset_y;

  gimp_display_shell_scroll_clamp_and_update (shell);

  gimp_display_shell_scrolled (shell);

  gimp_display_shell_expose_full (shell);

  /* re-enable the active tool */
  gimp_display_shell_resume (shell);
}
void
gimp_display_shell_layer_select_init (GimpDisplayShell *shell,
                                      gint              move,
                                      guint32           time)
{
  LayerSelect *layer_select;
  GimpImage   *image;
  GimpLayer   *layer;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  image = gimp_display_get_image (shell->display);

  layer = gimp_image_get_active_layer (image);

  if (! layer)
    return;

  layer_select = layer_select_new (image, layer,
                                   image->gimp->config->layer_preview_size);
  layer_select_advance (layer_select, move);

  gtk_window_set_screen (GTK_WINDOW (layer_select->window),
                         gtk_widget_get_screen (GTK_WIDGET (shell)));

  gtk_widget_show (layer_select->window);

  gdk_keyboard_grab (gtk_widget_get_window (layer_select->window), FALSE, time);
}
/**
 * gimp_display_shell_scale_image_is_within_viewport:
 * @shell:
 *
 * Returns: %TRUE if the (scaled) image is smaller than and within the
 *          viewport.
 **/
gboolean
gimp_display_shell_scale_image_is_within_viewport (GimpDisplayShell *shell,
                                                   gboolean         *horizontally,
                                                   gboolean         *vertically)
{
  gint     sw, sh;
  gboolean horizontally_dummy, vertically_dummy;

  g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);

  if (! horizontally) horizontally = &horizontally_dummy;
  if (! vertically)   vertically   = &vertically_dummy;

  gimp_display_shell_scale_get_image_size (shell, &sw, &sh);

  *horizontally = sw              <= shell->disp_width       &&
                  shell->offset_x <= 0                       &&
                  shell->offset_x >= sw - shell->disp_width;

  *vertically   = sh              <= shell->disp_height      &&
                  shell->offset_y <= 0                       &&
                  shell->offset_y >= sh - shell->disp_height;

  return *vertically && *horizontally;
}
/**
 * gimp_display_shell_scale_by_values:
 * @shell:         the #GimpDisplayShell
 * @scale:         the new scale
 * @offset_x:      the new X offset
 * @offset_y:      the new Y offset
 * @resize_window: whether the display window should be resized
 *
 * Directly sets the image scale and image offsets used by the display. If
 * @resize_window is %TRUE then the display window is resized to better
 * accommodate the image, see gimp_display_shell_shrink_wrap().
 **/
void
gimp_display_shell_scale_by_values (GimpDisplayShell *shell,
                                    gdouble           scale,
                                    gint              offset_x,
                                    gint              offset_y,
                                    gboolean          resize_window)
{
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  /*  Abort early if the values are all setup already. We don't
   *  want to inadvertently resize the window (bug #164281).
   */
  if (SCALE_EQUALS (gimp_zoom_model_get_factor (shell->zoom), scale) &&
      shell->offset_x == offset_x &&
      shell->offset_y == offset_y)
    return;

  gimp_display_shell_scale_save_revert_values (shell);

  /* freeze the active tool */
  gimp_display_shell_pause (shell);

  gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale);

  shell->offset_x = offset_x;
  shell->offset_y = offset_y;

  gimp_display_shell_scale_resize (shell, resize_window, FALSE);

  /* re-enable the active tool */
  gimp_display_shell_resume (shell);
}
void
gimp_display_shell_filter_set (GimpDisplayShell      *shell,
                               GimpColorDisplayStack *stack)
{
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
  g_return_if_fail (stack == NULL || GIMP_IS_COLOR_DISPLAY_STACK (stack));

  if (stack == shell->filter_stack)
    return;

  if (shell->filter_stack)
    {
      g_signal_handlers_disconnect_by_func (shell->filter_stack,
                                            gimp_display_shell_filter_changed,
                                            shell);

      g_object_unref (shell->filter_stack);
    }

  shell->filter_stack = stack;

  if (shell->filter_stack)
    {
      g_object_ref (shell->filter_stack);

      g_signal_connect (shell->filter_stack, "changed",
                        G_CALLBACK (gimp_display_shell_filter_changed),
                        shell);
    }

  gimp_display_shell_filter_changed (NULL, shell);
}
/**
 * gimp_display_shell_scale_can_revert:
 * @shell: the #GimpDisplayShell
 *
 * Return value: %TRUE if a previous display scale exists, otherwise %FALSE.
 **/
gboolean
gimp_display_shell_scale_can_revert (GimpDisplayShell *shell)
{
  g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);

  return (shell->last_scale > SCALE_EPSILON);
}
/**
 * gimp_display_shell_transform_xy:
 * @shell:
 * @x:
 * @y:
 * @nx:
 * @ny:
 *
 * Transforms an image coordinate to a shell coordinate.
 **/
void
gimp_display_shell_transform_xy (const GimpDisplayShell *shell,
                                 gdouble                 x,
                                 gdouble                 y,
                                 gint                   *nx,
                                 gint                   *ny)
{
    gint64 tx;
    gint64 ty;

    g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
    g_return_if_fail (nx != NULL);
    g_return_if_fail (ny != NULL);

    tx = ((gint64) x * shell->x_src_dec) / shell->x_dest_inc;
    ty = ((gint64) y * shell->y_src_dec) / shell->y_dest_inc;

    tx -= shell->offset_x;
    ty -= shell->offset_y;

    /* The projected coordinates might overflow a gint in the case of big
       images at high zoom levels, so we clamp them here to avoid problems.  */
    *nx = CLAMP (tx, G_MININT, G_MAXINT);
    *ny = CLAMP (ty, G_MININT, G_MAXINT);
}
/**
 * gimp_display_shell_untransform_xy:
 * @shell:       a #GimpDisplayShell
 * @x:           x coordinate in display coordinates
 * @y:           y coordinate in display coordinates
 * @nx:          returns x oordinate in image coordinates
 * @ny:          returns y coordinate in image coordinates
 * @round:       if %TRUE, round the results to the nearest integer;
 *               if %FALSE, simply cast them to @gint.
 *
 * Transform from display coordinates to image coordinates, so that
 * points on the display can be mapped to the corresponding points
 * in the image.
 **/
void
gimp_display_shell_untransform_xy (const GimpDisplayShell *shell,
                                   gint                    x,
                                   gint                    y,
                                   gint                   *nx,
                                   gint                   *ny,
                                   gboolean                round)
{
    gint64 tx;
    gint64 ty;

    g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
    g_return_if_fail (nx != NULL);
    g_return_if_fail (ny != NULL);

    tx = (gint64) x + shell->offset_x;
    ty = (gint64) y + shell->offset_y;

    tx *= shell->x_dest_inc;
    ty *= shell->y_dest_inc;

    tx += round ? shell->x_dest_inc : shell->x_dest_inc >> 1;
    ty += round ? shell->y_dest_inc : shell->y_dest_inc >> 1;

    tx /= shell->x_src_dec;
    ty /= shell->y_src_dec;

    *nx = CLAMP (tx, G_MININT, G_MAXINT);
    *ny = CLAMP (ty, G_MININT, G_MAXINT);
}
Beispiel #10
0
void
gimp_display_shell_constrain_line (GimpDisplayShell *shell,
                                   gdouble           start_x,
                                   gdouble           start_y,
                                   gdouble          *end_x,
                                   gdouble          *end_y,
                                   gint              n_snap_lines)
{
  gdouble offset_angle;
  gdouble xres, yres;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
  g_return_if_fail (end_x != NULL);
  g_return_if_fail (end_y != NULL);

  gimp_display_shell_get_constrained_line_params (shell,
                                                  &offset_angle,
                                                  &xres, &yres);

  gimp_constrain_line (start_x, start_y,
                       end_x,   end_y,
                       n_snap_lines,
                       offset_angle,
                       xres, yres);
}
/**
 * gimp_display_shell_scale_to:
 * @shell:
 * @scale:
 * @viewport_x:
 * @viewport_y:
 *
 * Zooms. The display offsets are adjusted so that the point specified
 * by @x and @y doesn't change it's position on screen.
 **/
static void
gimp_display_shell_scale_to (GimpDisplayShell *shell,
                             gdouble           scale,
                             gint              viewport_x,
                             gint              viewport_y)
{
  gdouble scale_x, scale_y;
  gdouble image_focus_x, image_focus_y;
  gint    target_offset_x, target_offset_y;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  if (! shell->display)
    return;

  gimp_display_shell_untransform_xy_f (shell,
                                       viewport_x,
                                       viewport_y,
                                       &image_focus_x,
                                       &image_focus_y);

  gimp_display_shell_calculate_scale_x_and_y (shell, scale, &scale_x, &scale_y);

  target_offset_x = scale_x * image_focus_x - viewport_x;
  target_offset_y = scale_y * image_focus_y - viewport_y;

  /* Note that we never come here if we need to
   * resize_windows_on_zoom
   */
  gimp_display_shell_scale_by_values (shell,
                                      scale,
                                      target_offset_x,
                                      target_offset_y,
                                      FALSE);
}
Beispiel #12
0
void
gimp_display_shell_get_constrained_line_params (GimpDisplayShell *shell,
                                                gdouble          *offset_angle,
                                                gdouble          *xres,
                                                gdouble          *yres)
{
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
  g_return_if_fail (offset_angle != NULL);
  g_return_if_fail (xres != NULL);
  g_return_if_fail (yres != NULL);

  if (shell->flip_horizontally ^ shell->flip_vertically)
    *offset_angle = +shell->rotate_angle;
  else
    *offset_angle = -shell->rotate_angle;

  *xres = 1.0;
  *yres = 1.0;

  if (! shell->dot_for_dot)
    {
      GimpImage *image = gimp_display_get_image (shell->display);

      if (image)
        gimp_image_get_resolution (image, xres, yres);
    }
}
/**
 * gimp_display_shell_untransform_coords:
 * @shell:          a #GimpDisplayShell
 * @display_coords: display coordinates
 * @image_coords:   returns the corresponding image coordinates
 *
 * Transforms from display coordinates to image coordinates, so that
 * points on the display can be mapped to points in the image.
 **/
void
gimp_display_shell_untransform_coords (const GimpDisplayShell *shell,
                                       const GimpCoords       *display_coords,
                                       GimpCoords             *image_coords)
{
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
  g_return_if_fail (display_coords != NULL);
  g_return_if_fail (image_coords != NULL);

  *image_coords = *display_coords;

  if (shell->rotate_untransform)
    cairo_matrix_transform_point (shell->rotate_untransform,
                                  &image_coords->x,
                                  &image_coords->y);

  image_coords->x += shell->offset_x;
  image_coords->y += shell->offset_y;

  image_coords->x /= shell->scale_x;
  image_coords->y /= shell->scale_y;

  image_coords->xscale = shell->scale_x;
  image_coords->yscale = shell->scale_y;

}
/**
 * gimp_display_shell_unrotate_xy:
 * @shell:       a #GimpDisplayShell
 * @x:           x coordinate in rotated display coordinates
 * @y:           y coordinate in rotated display coordinates
 * @nx:          returns x oordinate in unrotated display coordinates
 * @ny:          returns y coordinate in unrotated display coordinates
 *
 * Rotate from rotated display coordinates to unrotated display
 * coordinates.
 **/
void
gimp_display_shell_unrotate_xy (const GimpDisplayShell *shell,
                                gint                    x,
                                gint                    y,
                                gint                   *nx,
                                gint                   *ny)
{
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
  g_return_if_fail (nx != NULL);
  g_return_if_fail (ny != NULL);

  if (shell->rotate_untransform)
    {
      gdouble fx = x;
      gdouble fy = y;

      cairo_matrix_transform_point (shell->rotate_untransform, &fy, &fy);

      *nx = CLAMP (fx, G_MININT, G_MAXINT);
      *ny = CLAMP (fy, G_MININT, G_MAXINT);
    }
  else
    {
      *nx = x;
      *ny = y;
    }
}
Beispiel #15
0
void
gimp_display_shell_scale_drag (GimpDisplayShell *shell,
                               gdouble           start_x,
                               gdouble           start_y,
                               gdouble           delta_x,
                               gdouble           delta_y)
{
  gdouble scale;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  scale = gimp_zoom_model_get_factor (shell->zoom);

  gimp_display_shell_push_zoom_focus_pointer_pos (shell, start_x, start_y);

  if (delta_y > 0)
    {
      gimp_display_shell_scale (shell,
                                GIMP_ZOOM_TO,
                                scale * 1.1,
                                GIMP_ZOOM_FOCUS_POINTER);
    }
  else if (delta_y < 0)
    {
      gimp_display_shell_scale (shell,
                                GIMP_ZOOM_TO,
                                scale * 0.9,
                                GIMP_ZOOM_FOCUS_POINTER);
    }
}
/**
 * gimp_display_shell_transform_segments:
 * @shell:       a #GimpDisplayShell
 * @src_segs:    array of segments in image coordinates
 * @dest_segs:   returns the corresponding segments in display coordinates
 * @n_segs:      number of segments
 *
 * Transforms from image coordinates to display coordinates, so that
 * objects can be rendered at the correct points on the display.
 **/
void
gimp_display_shell_transform_segments (const GimpDisplayShell *shell,
                                       const GimpBoundSeg     *src_segs,
                                       GimpSegment            *dest_segs,
                                       gint                    n_segs,
                                       gdouble                 offset_x,
                                       gdouble                 offset_y)
{
    gint i;

    g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

    for (i = 0; i < n_segs ; i++)
    {
        gdouble x1, x2;
        gdouble y1, y2;

        x1 = src_segs[i].x1 + offset_x;
        x2 = src_segs[i].x2 + offset_x;
        y1 = src_segs[i].y1 + offset_y;
        y2 = src_segs[i].y2 + offset_y;

        dest_segs[i].x1 = SCALEX (shell, x1) - shell->offset_x;
        dest_segs[i].x2 = SCALEX (shell, x2) - shell->offset_x;
        dest_segs[i].y1 = SCALEY (shell, y1) - shell->offset_y;
        dest_segs[i].y2 = SCALEY (shell, y2) - shell->offset_y;
    }
}
Beispiel #17
0
/**
 * gimp_display_shell_get_rotated_scale:
 * @shell:   the #GimpDisplayShell
 * @scale_x: horizontal scale output
 * @scale_y: vertical scale output
 *
 * Returns the screen space horizontal and vertical scaling
 * factors, taking rotation into account.
 **/
void
gimp_display_shell_get_rotated_scale (GimpDisplayShell *shell,
                                      gdouble          *scale_x,
                                      gdouble          *scale_y)
{
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  if (shell->rotate_angle == 0.0 || shell->scale_x == shell->scale_y)
    {
      if (scale_x) *scale_x = shell->scale_x;
      if (scale_y) *scale_y = shell->scale_y;
    }
  else
    {
      gdouble a     = G_PI * shell->rotate_angle / 180.0;
      gdouble cos_a = cos (a);
      gdouble sin_a = sin (a);

      if (scale_x) *scale_x = 1.0 / sqrt (SQR (cos_a / shell->scale_x) +
                                          SQR (sin_a / shell->scale_y));

      if (scale_y) *scale_y = 1.0 / sqrt (SQR (cos_a / shell->scale_y) +
                                          SQR (sin_a / shell->scale_x));
    }
}
/**
 * gimp_display_shell_scroll_center_image:
 * @shell:
 * @horizontally:
 * @vertically:
 *
 * Centers the image in the display shell on the desired axes.
 *
 **/
void
gimp_display_shell_scroll_center_image (GimpDisplayShell *shell,
                                        gboolean          horizontally,
                                        gboolean          vertically)
{
  gint sw, sh;
  gint target_offset_x, target_offset_y;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  if (! shell->display                          ||
      ! gimp_display_get_image (shell->display) ||
      (! vertically && ! horizontally))
    return;

  target_offset_x = shell->offset_x;
  target_offset_y = shell->offset_y;

  gimp_display_shell_scale_get_image_size (shell, &sw, &sh);

  if (horizontally)
    {
      target_offset_x = (sw - shell->disp_width) / 2;
    }

  if (vertically)
    {
      target_offset_y = (sh - shell->disp_height) / 2;
    }

  gimp_display_shell_scroll_set_offset (shell,
                                        target_offset_x,
                                        target_offset_y);
}
GimpColorDisplayStack *
gimp_display_shell_filter_new (GimpDisplayShell *shell,
                               GimpColorConfig  *config)
{
  g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
  g_return_val_if_fail (GIMP_IS_COLOR_CONFIG (config), NULL);

  if (config->display_module)
    {
      GType type = g_type_from_name (config->display_module);

      if (g_type_is_a (type, GIMP_TYPE_COLOR_DISPLAY))
        {
          GimpColorDisplay      *display;
          GimpColorDisplayStack *stack;

          display = g_object_new (type,
                                  "color-config",  config,
                                  "color-managed", shell,
                                  NULL);

          stack = gimp_color_display_stack_new ();

          gimp_color_display_stack_add (stack, display);
          g_object_unref (display);

          return stack;
        }
    }

  return NULL;
}
/**
 * gimp_display_shell_scroll_setup_vscrollbar:
 * @shell:
 * @value:
 *
 * Setup the limits of the vertical scrollbar
 *
 **/
void
gimp_display_shell_scroll_setup_vscrollbar (GimpDisplayShell *shell,
                                            gdouble           value)
{
  gint    sh;
  gdouble lower;
  gdouble upper;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  if (! shell->display ||
      ! gimp_display_get_image (shell->display))
    return;

  gimp_display_shell_scale_get_image_size (shell, NULL, &sh);

  if (shell->disp_height < sh)
    {
      lower = MIN (value, 0);
      upper = MAX (value + shell->disp_height, sh);
    }
  else
    {
      lower = MIN (value, -(shell->disp_height - sh) / 2);
      upper = MAX (value + shell->disp_height,
                   sh + (shell->disp_height - sh) / 2);
    }

  g_object_set (shell->vsbdata,
                "lower",          lower,
                "upper",          upper,
                "step-increment", (gdouble) MAX (shell->scale_y,
                                                 MINIMUM_STEP_AMOUNT),
                NULL);
}
/**
 * gimp_display_shell_scale_set_dot_for_dot:
 * @shell:        the #GimpDisplayShell
 * @dot_for_dot:  whether "Dot for Dot" should be enabled
 *
 * If @dot_for_dot is set to %TRUE then the "Dot for Dot" mode (where image and
 * screen pixels are of the same size) is activated. Dually, the mode is
 * disabled if @dot_for_dot is %FALSE.
 **/
void
gimp_display_shell_scale_set_dot_for_dot (GimpDisplayShell *shell,
                                          gboolean          dot_for_dot)
{
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  if (dot_for_dot != shell->dot_for_dot)
    {
      GimpDisplayConfig *config = shell->display->config;
      gboolean           resize_window;

      /* Resize windows only in multi-window mode */
      resize_window = (config->resize_windows_on_zoom &&
                       ! GIMP_GUI_CONFIG (config)->single_window_mode);

      /* freeze the active tool */
      gimp_display_shell_pause (shell);

      shell->dot_for_dot = dot_for_dot;

      gimp_display_shell_scale_update (shell);

      gimp_display_shell_scale_resize (shell, resize_window, FALSE);

      /* re-enable the active tool */
      gimp_display_shell_resume (shell);
    }
}
void
gimp_display_shell_expose_region (GimpDisplayShell *shell,
                                  cairo_region_t   *region)
{
  GdkRegion *gdk_region;
  gint       n_rectangles;
  gint       i;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
  g_return_if_fail (region != NULL);

  if (! gtk_widget_get_realized (shell->canvas))
    return;

  gdk_region = gdk_region_new ();
  n_rectangles = cairo_region_num_rectangles (region);

  for (i = 0; i < n_rectangles; i++)
    {
      cairo_rectangle_int_t rectangle;

      cairo_region_get_rectangle (region, i, &rectangle);

      gdk_region_union_with_rect (gdk_region, (GdkRectangle *) &rectangle);
    }

  gdk_window_invalidate_region (gtk_widget_get_window (shell->canvas),
                                gdk_region, TRUE);
  gdk_region_destroy (gdk_region);
}
/**
 * gimp_display_shell_scale_fill:
 * @shell: the #GimpDisplayShell
 *
 * Sets the scale such that the entire display area is precisely
 * filled by the image.
 **/
void
gimp_display_shell_scale_fill (GimpDisplayShell *shell)
{
  GimpImage *image;
  gint       image_width;
  gint       image_height;
  gdouble    xres;
  gdouble    yres;
  gdouble    zoom_factor;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  image = gimp_display_get_image (shell->display);

  image_width  = gimp_image_get_width  (image);
  image_height = gimp_image_get_height (image);

  gimp_image_get_resolution (image, &xres, &yres);

  if (! shell->dot_for_dot)
    {
      image_width  = ROUND (image_width  * shell->monitor_xres / xres);
      image_height = ROUND (image_height * shell->monitor_yres / yres);
    }

  zoom_factor = MAX ((gdouble) shell->disp_width  / (gdouble) image_width,
                     (gdouble) shell->disp_height / (gdouble) image_height);

  gimp_display_shell_scale (shell,
                            GIMP_ZOOM_TO,
                            zoom_factor,
                            GIMP_ZOOM_FOCUS_BEST_GUESS);

  gimp_display_shell_scroll_center_image (shell, TRUE, TRUE);
}
void
gimp_display_shell_expose_full (GimpDisplayShell *shell)
{
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  gtk_widget_queue_draw (shell->canvas);
}
/**
 * gimp_display_shell_scale_resize:
 * @shell:          the #GimpDisplayShell
 * @resize_window:  whether the display window should be resized
 * @grow_only:      whether shrinking of the window is allowed or not
 *
 * Function commonly called after a change in display scale to make the changes
 * visible to the user. If @resize_window is %TRUE then the display window is
 * resized to accommodate the display image as per
 * gimp_display_shell_shrink_wrap().
 **/
void
gimp_display_shell_scale_resize (GimpDisplayShell *shell,
                                 gboolean          resize_window,
                                 gboolean          grow_only)
{
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  /* freeze the active tool */
  gimp_display_shell_pause (shell);

  if (resize_window)
    {
      GimpImageWindow *window = gimp_display_shell_get_window (shell);

      if (window && gimp_image_window_get_active_shell (window) == shell)
        {
          gimp_image_window_shrink_wrap (window, grow_only);
        }
    }

  gimp_display_shell_scroll_clamp_and_update (shell);
  gimp_display_shell_scaled (shell);

  gimp_display_shell_expose_full (shell);

  /* re-enable the active tool */
  gimp_display_shell_resume (shell);
}
void
gimp_display_shell_clear_software_cursor (GimpDisplayShell *shell)
{
  GimpStatusbar     *statusbar;
  GimpSessionInfo   *session_info;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  gimp_canvas_item_set_visible (shell->cursor, FALSE);

  statusbar = gimp_display_shell_get_statusbar (shell);

  gimp_statusbar_clear_cursor (statusbar);

  session_info = gimp_dialog_factory_find_session_info (gimp_dialog_factory_get_singleton (),
                                                        "gimp-cursor-view");
  if (session_info && gimp_session_info_get_widget (session_info))
    {
      GtkWidget *cursor_view;

      cursor_view = gtk_bin_get_child (GTK_BIN (gimp_session_info_get_widget (session_info)));

      if (cursor_view)
        gimp_cursor_view_clear_cursor (GIMP_CURSOR_VIEW (cursor_view));
    }
}
void
gimp_display_shell_selection_free (GimpDisplayShell *shell)
{
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  if (shell->selection)
    {
      Selection *selection = shell->selection;

      selection_stop (selection);

      g_signal_handlers_disconnect_by_func (shell,
                                            selection_window_state_event,
                                            selection);
      g_signal_handlers_disconnect_by_func (shell,
                                            selection_visibility_notify_event,
                                            selection);

      selection_free_segs (selection);

      g_slice_free (Selection, selection);

      shell->selection = NULL;
    }
}
Beispiel #28
0
/**
 * gimp_display_shell_scale_get_image_bounds:
 * @shell:
 * @x:
 * @y:
 * @w:
 * @h:
 *
 * Gets the screen-space boudning box of the image, after it has
 * been transformed (i.e., scaled, rotated, and scrolled).
 **/
void
gimp_display_shell_scale_get_image_bounds (GimpDisplayShell *shell,
                                           gint             *x,
                                           gint             *y,
                                           gint             *w,
                                           gint             *h)
{
  GimpImage *image;
  gdouble    x1, y1;
  gdouble    x2, y2;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  image = gimp_display_get_image (shell->display);

  gimp_display_shell_transform_bounds (shell,
                                       0, 0,
                                       gimp_image_get_width (image),
                                       gimp_image_get_height (image),
                                       &x1, &y1,
                                       &x2, &y2);

  x1 = ceil (x1);
  y1 = ceil (y1);
  x2 = floor (x2);
  y2 = floor (y2);

  if (x) *x = x1 + shell->offset_x;
  if (y) *y = y1 + shell->offset_y;
  if (w) *w = x2 - x1;
  if (h) *h = y2 - y1;
}
void
gimp_display_shell_close (GimpDisplayShell *shell,
                          gboolean          kill_it)
{
  GimpImage *image;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  image = shell->display->image;

  /*  FIXME: gimp_busy HACK not really appropriate here because we only
   *  want to prevent the busy image and display to be closed.  --Mitch
   */
  if (image->gimp->busy)
    return;

  /*  If the image has been modified, give the user a chance to save
   *  it before nuking it--this only applies if its the last view
   *  to an image canvas.  (a image with disp_count = 1)
   */
  if (! kill_it              &&
      image->disp_count == 1 &&
      image->dirty           &&
      GIMP_DISPLAY_CONFIG (image->gimp->config)->confirm_on_close)
    {
      gimp_display_shell_close_dialog (shell, image);
    }
  else
    {
      gimp_display_delete (shell->display);
    }
}
/**
 * gimp_display_shell_unzoom_xy:
 * @shell:       a #GimpDisplayShell
 * @x:           x coordinate in display coordinates
 * @y:           y coordinate in display coordinates
 * @nx:          returns x oordinate in image coordinates
 * @ny:          returns y coordinate in image coordinates
 * @round:       if %TRUE, round the results to the nearest integer;
 *               if %FALSE, simply cast them to @gint.
 *
 * Zoom from display coordinates to image coordinates, so that
 * points on the display can be mapped to the corresponding points
 * in the image.
 **/
void
gimp_display_shell_unzoom_xy (const GimpDisplayShell *shell,
                              gint                    x,
                              gint                    y,
                              gint                   *nx,
                              gint                   *ny,
                              gboolean                round)
{
  gint64 tx;
  gint64 ty;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
  g_return_if_fail (nx != NULL);
  g_return_if_fail (ny != NULL);

  if (round)
    {
      tx = SIGNED_ROUND (((gdouble) x + shell->offset_x) / shell->scale_x);
      ty = SIGNED_ROUND (((gdouble) y + shell->offset_y) / shell->scale_y);
    }
  else
    {
      tx = ((gint64) x + shell->offset_x) / shell->scale_x;
      ty = ((gint64) y + shell->offset_y) / shell->scale_y;
    }

  *nx = CLAMP (tx, G_MININT, G_MAXINT);
  *ny = CLAMP (ty, G_MININT, G_MAXINT);
}