/**
 * 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);
}
Example #2
0
static void
gimp_zoom_model_zoom_out (GimpZoomModel *model)
{
  GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model);

  if (priv->value > priv->minimum)
    gimp_zoom_model_zoom (model, GIMP_ZOOM_OUT, 0.0);
}
Example #3
0
static void
gimp_zoom_model_zoom_in (GimpZoomModel *model)
{
  GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model);

  if (priv->value < priv->maximum)
    gimp_zoom_model_zoom (model, GIMP_ZOOM_IN, 0.0);
}
Example #4
0
static void
update_zoom_values (GtkAdjustment   *adj,
                    ScaleDialogData *dialog)
{
  gint    num, denom;
  gdouble scale;

  g_signal_handlers_block_by_func (dialog->scale_adj,
                                   update_zoom_values,
                                   dialog);
  g_signal_handlers_block_by_func (dialog->num_adj,
                                   update_zoom_values,
                                   dialog);
  g_signal_handlers_block_by_func (dialog->denom_adj,
                                   update_zoom_values,
                                   dialog);

  if (adj == dialog->scale_adj)
    {
      scale = gtk_adjustment_get_value (dialog->scale_adj);

      gimp_zoom_model_zoom (dialog->model, GIMP_ZOOM_TO, scale / 100.0);
      gimp_zoom_model_get_fraction (dialog->model, &num, &denom);

      gtk_adjustment_set_value (dialog->num_adj, num);
      gtk_adjustment_set_value (dialog->denom_adj, denom);
    }
  else /* fraction adjustments */
    {
      scale = (gtk_adjustment_get_value (dialog->num_adj) /
               gtk_adjustment_get_value (dialog->denom_adj));

      gtk_adjustment_set_value (dialog->scale_adj, scale * 100);
    }

  g_signal_handlers_unblock_by_func (dialog->scale_adj,
                                     update_zoom_values,
                                     dialog);
  g_signal_handlers_unblock_by_func (dialog->num_adj,
                                     update_zoom_values,
                                     dialog);
  g_signal_handlers_unblock_by_func (dialog->denom_adj,
                                     update_zoom_values,
                                     dialog);
}
void
gimp_display_shell_canvas_size_allocate (GtkWidget        *widget,
                                         GtkAllocation    *allocation,
                                         GimpDisplayShell *shell)
{
  /*  are we in destruction?  */
  if (! shell->display || ! gimp_display_get_shell (shell->display))
    return;

  if ((shell->disp_width  != allocation->width) ||
      (shell->disp_height != allocation->height))
    {
      if (shell->zoom_on_resize   &&
          shell->disp_width  > 64 &&
          shell->disp_height > 64 &&
          allocation->width  > 64 &&
          allocation->height > 64)
        {
          gdouble scale = gimp_zoom_model_get_factor (shell->zoom);
          gint    offset_x;
          gint    offset_y;

          /* FIXME: The code is a bit of a mess */

          /*  multiply the zoom_factor with the ratio of the new and
           *  old canvas diagonals
           */
          scale *= (sqrt (SQR (allocation->width) +
                          SQR (allocation->height)) /
                    sqrt (SQR (shell->disp_width) +
                          SQR (shell->disp_height)));

          offset_x = UNSCALEX (shell, shell->offset_x);
          offset_y = UNSCALEX (shell, shell->offset_y);

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

          shell->offset_x = SCALEX (shell, offset_x);
          shell->offset_y = SCALEY (shell, offset_y);
        }

      shell->disp_width  = allocation->width;
      shell->disp_height = allocation->height;

      /* When we size-allocate due to resize of the top level window,
       * we want some additional logic. Don't apply it on
       * zoom_on_resize though.
       */
      if (shell->size_allocate_from_configure_event &&
          ! shell->zoom_on_resize)
        {
          gboolean center_horizontally;
          gboolean center_vertically;
          gint     target_offset_x;
          gint     target_offset_y;
          gint     sw;
          gint     sh;

          gimp_display_shell_scale_get_image_size (shell, &sw, &sh);

          center_horizontally = sw <= shell->disp_width;
          center_vertically   = sh <= shell->disp_height;

          gimp_display_shell_scroll_center_image (shell,
                                                  center_horizontally,
                                                  center_vertically);

          /* This is basically the best we can do before we get an
           * API for storing the image offset at the start of an
           * image window resize using the mouse
           */
          target_offset_x = shell->offset_x;
          target_offset_y = shell->offset_y;

          if (! center_horizontally)
            {
              target_offset_x = MAX (shell->offset_x, 0);
            }

          if (! center_vertically)
            {
              target_offset_y = MAX (shell->offset_y, 0);
            }

          gimp_display_shell_scroll_set_offset (shell,
                                                target_offset_x,
                                                target_offset_y);
        }

      gimp_display_shell_scroll_clamp_and_update (shell);
      gimp_display_shell_scaled (shell);

      /* Reset */
      shell->size_allocate_from_configure_event = FALSE;
    }
}
void
gimp_display_shell_set_initial_scale (GimpDisplayShell *shell,
                                      gdouble           scale,
                                      gint             *display_width,
                                      gint             *display_height)
{
  GimpImage *image;
  GdkScreen *screen;
  gint       image_width;
  gint       image_height;
  gint       shell_width;
  gint       shell_height;
  gint       screen_width;
  gint       screen_height;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  image = gimp_display_get_image (shell->display);

  screen = gtk_widget_get_screen (GTK_WIDGET (shell));

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

  screen_width  = gdk_screen_get_width (screen)  * 0.75;
  screen_height = gdk_screen_get_height (screen) * 0.75;

  /* We need to zoom before we use SCALE[XY] */
  gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale);

  shell_width  = SCALEX (shell, image_width);
  shell_height = SCALEY (shell, image_height);

  if (shell->display->config->initial_zoom_to_fit)
    {
      /*  Limit to the size of the screen...  */
      if (shell_width > screen_width || shell_height > screen_height)
        {
          gdouble new_scale;
          gdouble current = gimp_zoom_model_get_factor (shell->zoom);

          new_scale = current * MIN (((gdouble) screen_height) / shell_height,
                                     ((gdouble) screen_width)  / shell_width);

          new_scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, new_scale);

          /*  Since zooming out might skip a zoom step we zoom in
           *  again and test if we are small enough.
           */
          gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO,
                                gimp_zoom_model_zoom_step (GIMP_ZOOM_IN,
                                                           new_scale));

          if (SCALEX (shell, image_width) > screen_width ||
              SCALEY (shell, image_height) > screen_height)
            gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, new_scale);

          shell_width  = SCALEX (shell, image_width);
          shell_height = SCALEY (shell, image_height);
        }
    }
  else
    {
      /*  Set up size like above, but do not zoom to fit. Useful when
       *  working on large images.
       */
      if (shell_width > screen_width)
        shell_width = screen_width;

      if (shell_height > screen_height)
        shell_height = screen_height;
    }

  if (display_width)
    *display_width = shell_width;

  if (display_height)
    *display_height = shell_height;
}
/**
 * gimp_display_shell_scale:
 * @shell:     the #GimpDisplayShell
 * @zoom_type: whether to zoom in, our or to a specific scale
 * @scale:     ignored unless @zoom_type == %GIMP_ZOOM_TO
 *
 * This function figures out the context of the zoom and behaves
 * appropriatley thereafter.
 *
 **/
void
gimp_display_shell_scale (GimpDisplayShell *shell,
                          GimpZoomType      zoom_type,
                          gdouble           new_scale,
                          GimpZoomFocus     zoom_focus)
{
  gdouble current_scale;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
  g_return_if_fail (shell->canvas != NULL);

  current_scale = gimp_zoom_model_get_factor (shell->zoom);

  if (zoom_type != GIMP_ZOOM_TO)
    new_scale = gimp_zoom_model_zoom_step (zoom_type, current_scale);

  if (! SCALE_EQUALS (new_scale, current_scale))
    {
      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);

      if (resize_window)
        {
          /* If the window is resized on zoom, simply do the zoom and
           * get things rolling
           */
          gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, new_scale);

          gimp_display_shell_scale_resize (shell, TRUE, FALSE);
        }
      else
        {
          gboolean starts_fitting_horiz;
          gboolean starts_fitting_vert;
          gboolean zoom_focus_almost_centered_horiz;
          gboolean zoom_focus_almost_centered_vert;
          gboolean image_center_almost_centered_horiz;
          gboolean image_center_almost_centered_vert;
          gdouble  x, y;
          gint     image_center_x;
          gint     image_center_y;

          gimp_display_shell_scale_get_zoom_focus (shell,
                                                   new_scale,
                                                   current_scale,
                                                   &x,
                                                   &y,
                                                   zoom_focus);
          gimp_display_shell_scale_get_image_center_viewport (shell,
                                                              &image_center_x,
                                                              &image_center_y);

          gimp_display_shell_scale_to (shell, new_scale, x, y);


          /* If an image axis started to fit due to zooming out or if
           * the focus point is as good as in the center, center on
           * that axis
           */
          gimp_display_shell_scale_image_starts_to_fit (shell,
                                                        new_scale,
                                                        current_scale,
                                                        &starts_fitting_horiz,
                                                        &starts_fitting_vert);

          gimp_display_shell_scale_viewport_coord_almost_centered (shell,
                                                                   x,
                                                                   y,
                                                                   &zoom_focus_almost_centered_horiz,
                                                                   &zoom_focus_almost_centered_vert);
          gimp_display_shell_scale_viewport_coord_almost_centered (shell,
                                                                   image_center_x,
                                                                   image_center_y,
                                                                   &image_center_almost_centered_horiz,
                                                                   &image_center_almost_centered_vert);

          gimp_display_shell_scroll_center_image (shell,
                                                  starts_fitting_horiz ||
                                                  (zoom_focus_almost_centered_horiz &&
                                                   image_center_almost_centered_horiz),
                                                  starts_fitting_vert ||
                                                  (zoom_focus_almost_centered_vert &&
                                                   image_center_almost_centered_vert));
        }
    }
}
Example #8
0
void
gimp_display_shell_set_initial_scale (GimpDisplayShell *shell,
                                      gdouble           scale,
                                      gint             *display_width,
                                      gint             *display_height)
{
  GimpImage    *image;
  GdkRectangle  workarea;
  gint          image_width;
  gint          image_height;
  gint          monitor_width;
  gint          monitor_height;
  gint          shell_width;
  gint          shell_height;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  image = gimp_display_get_image (shell->display);

  gdk_monitor_get_workarea (shell->initial_monitor, &workarea);

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

  monitor_width  = workarea.width  * 0.75;
  monitor_height = workarea.height * 0.75;

  /* We need to zoom before we use SCALE[XY] */
  gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale);

  shell_width  = SCALEX (shell, image_width);
  shell_height = SCALEY (shell, image_height);

  if (shell->display->config->initial_zoom_to_fit)
    {
      /*  Limit to the size of the monitor...  */
      if (shell_width > monitor_width || shell_height > monitor_height)
        {
          gdouble new_scale;
          gdouble current = gimp_zoom_model_get_factor (shell->zoom);

          new_scale = current * MIN (((gdouble) monitor_height) / shell_height,
                                     ((gdouble) monitor_width)  / shell_width);

          new_scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, new_scale, 0.0);

          /*  Since zooming out might skip a zoom step we zoom in
           *  again and test if we are small enough.
           */
          gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO,
                                gimp_zoom_model_zoom_step (GIMP_ZOOM_IN,
                                                           new_scale, 0.0));

          if (SCALEX (shell, image_width)  > monitor_width ||
              SCALEY (shell, image_height) > monitor_height)
            gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, new_scale);

          shell_width  = SCALEX (shell, image_width);
          shell_height = SCALEY (shell, image_height);
        }
    }
  else
    {
      /*  Set up size like above, but do not zoom to fit. Useful when
       *  working on large images.
       */
      shell_width  = MIN (shell_width,  monitor_width);
      shell_height = MIN (shell_height, monitor_height);
    }

  if (display_width)  *display_width  = shell_width;
  if (display_height) *display_height = shell_height;
}
/**
 * gimp_display_shell_scale:
 * @shell:     the #GimpDisplayShell
 * @zoom_type: whether to zoom in, our or to a specific scale
 * @scale:     ignored unless @zoom_type == %GIMP_ZOOM_TO
 *
 * This function figures out the context of the zoom and behaves
 * appropriatley thereafter.
 *
 **/
void
gimp_display_shell_scale (GimpDisplayShell *shell,
                          GimpZoomType      zoom_type,
                          gdouble           new_scale,
                          GimpZoomFocus     zoom_focus)
{
  gint    x, y;
  gdouble current_scale;
  gdouble real_new_scale;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
  g_return_if_fail (shell->canvas != NULL);

  current_scale = gimp_zoom_model_get_factor (shell->zoom);

  if (zoom_type != GIMP_ZOOM_TO)
    {
      real_new_scale = gimp_zoom_model_zoom_step (zoom_type, current_scale);
    }
  else
    {
      real_new_scale = new_scale;
    }

  if (! SCALE_EQUALS (real_new_scale, current_scale))
    {
      if (shell->display->config->resize_windows_on_zoom)
        {
          GimpImageWindow *window = gimp_display_shell_get_window (shell);

          /* If the window is resized on zoom, simply do the zoom and
           * get things rolling
           */
          gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, real_new_scale);
          gimp_display_shell_scaled (shell);

          if (window && gimp_image_window_get_active_shell (window) == shell)
            {
              gimp_image_window_shrink_wrap (window, FALSE);
            }
        }
      else
        {
          gboolean starts_fitting_horiz;
          gboolean starts_fitting_vert;
          gboolean zoom_focus_almost_centered_horiz;
          gboolean zoom_focus_almost_centered_vert;
          gboolean image_center_almost_centered_horiz;
          gboolean image_center_almost_centered_vert;
          gint     image_center_x;
          gint     image_center_y;

          gimp_display_shell_scale_get_zoom_focus (shell,
                                                   real_new_scale,
                                                   current_scale,
                                                   &x,
                                                   &y,
                                                   zoom_focus);
          gimp_display_shell_scale_get_image_center_viewport (shell,
                                                              &image_center_x,
                                                              &image_center_y);

          gimp_display_shell_scale_to (shell, real_new_scale, x, y);


          /* If an image axis started to fit due to zooming out or if
           * the focus point is as good as in the center, center on
           * that axis
           */
          gimp_display_shell_scale_image_starts_to_fit (shell,
                                                        real_new_scale,
                                                        current_scale,
                                                        &starts_fitting_horiz,
                                                        &starts_fitting_vert);

          gimp_display_shell_scale_viewport_coord_almost_centered (shell,
                                                                   x,
                                                                   y,
                                                                   &zoom_focus_almost_centered_horiz,
                                                                   &zoom_focus_almost_centered_vert);
          gimp_display_shell_scale_viewport_coord_almost_centered (shell,
                                                                   image_center_x,
                                                                   image_center_y,
                                                                   &image_center_almost_centered_horiz,
                                                                   &image_center_almost_centered_vert);
            
          gimp_display_shell_scroll_center_image (shell,
                                                  starts_fitting_horiz ||
                                                  (zoom_focus_almost_centered_horiz &&
                                                   image_center_almost_centered_horiz),
                                                  starts_fitting_vert ||
                                                  (zoom_focus_almost_centered_vert &&
                                                   image_center_almost_centered_vert));
        }
    }
}