Example #1
0
static void
gimp_align_tool_oper_update (GimpTool         *tool,
                             const GimpCoords *coords,
                             GdkModifierType   state,
                             gboolean          proximity,
                             GimpDisplay      *display)
{
    GimpAlignTool    *align_tool    = GIMP_ALIGN_TOOL (tool);
    GimpDisplayShell *shell         = gimp_display_get_shell (display);
    GimpImage        *image         = gimp_display_get_image (display);
    gint              snap_distance = display->config->snap_distance;
    gboolean          add;

    add = ((state & gimp_get_extend_selection_mask ()) &&
           align_tool->selected_objects);

    if (gimp_draw_tool_on_vectors (GIMP_DRAW_TOOL (tool), display,
                                   coords, snap_distance, snap_distance,
                                   NULL, NULL, NULL, NULL, NULL, NULL))
    {
        if (add)
            align_tool->function = ALIGN_TOOL_ADD_PATH;
        else
            align_tool->function = ALIGN_TOOL_PICK_PATH;
    }
    else if (gimp_display_shell_get_show_guides (shell) &&
             gimp_image_find_guide (image,
                                    coords->x, coords->y,
                                    FUNSCALEX (shell, snap_distance),
                                    FUNSCALEY (shell, snap_distance)))
    {
        if (add)
            align_tool->function = ALIGN_TOOL_ADD_GUIDE;
        else
            align_tool->function = ALIGN_TOOL_PICK_GUIDE;
    }
    else
    {
        GimpLayer *layer;

        layer = gimp_image_pick_layer_by_bounds (image, coords->x, coords->y);

        if (layer)
        {
            if (add)
                align_tool->function = ALIGN_TOOL_ADD_LAYER;
            else
                align_tool->function = ALIGN_TOOL_PICK_LAYER;
        }
        else
        {
            align_tool->function = ALIGN_TOOL_IDLE;
        }
    }

    gimp_align_tool_status_update (tool, display, state, proximity);
}
Example #2
0
static void
gimp_align_tool_oper_update (GimpTool        *tool,
                             GimpCoords      *coords,
                             GdkModifierType  state,
                             gboolean         proximity,
                             GimpDisplay     *display)
{
  GimpAlignTool      *align_tool  = GIMP_ALIGN_TOOL (tool);
  GimpDisplayShell   *shell       = GIMP_DISPLAY_SHELL (display->shell);
  gint                snap_distance;

  snap_distance =
    GIMP_DISPLAY_CONFIG (display->image->gimp->config)->snap_distance;

  if (gimp_draw_tool_on_vectors (GIMP_DRAW_TOOL (tool), display,
                                 coords, snap_distance, snap_distance,
                                 NULL, NULL, NULL, NULL, NULL, NULL))
    {
      if ((state & GDK_SHIFT_MASK) && align_tool->selected_objects)
        align_tool->function = ALIGN_TOOL_ADD_PATH;
      else
        align_tool->function = ALIGN_TOOL_PICK_PATH;
    }
  else if (gimp_display_shell_get_show_guides (shell) &&
           (NULL != gimp_image_find_guide (display->image,
                                           coords->x, coords->y,
                                           FUNSCALEX (shell, snap_distance),
                                           FUNSCALEY (shell, snap_distance))))
    {
      if ((state & GDK_SHIFT_MASK) && align_tool->selected_objects)
        align_tool->function = ALIGN_TOOL_ADD_GUIDE;
      else
        align_tool->function = ALIGN_TOOL_PICK_GUIDE;
    }
  else
    {
      GimpLayer *layer = select_layer_by_coords (display->image,
                                                 coords->x, coords->y);

      if (layer)
        {
          if ((state & GDK_SHIFT_MASK) && align_tool->selected_objects)
            align_tool->function = ALIGN_TOOL_ADD_LAYER;
          else
            align_tool->function = ALIGN_TOOL_PICK_LAYER;
        }
      else
        {
          align_tool->function = ALIGN_TOOL_IDLE;
        }
    }

  gimp_align_tool_status_update (tool, display, state, proximity);
}
Example #3
0
static void
gimp_flip_tool_oper_update (GimpTool         *tool,
                            const GimpCoords *coords,
                            GdkModifierType   state,
                            gboolean          proximity,
                            GimpDisplay      *display)
{
  GimpFlipTool     *flip      = GIMP_FLIP_TOOL (tool);
  GimpDrawTool     *draw_tool = GIMP_DRAW_TOOL (tool);
  GimpFlipOptions  *options   = GIMP_FLIP_TOOL_GET_OPTIONS (tool);
  GimpDisplayShell *shell     = gimp_display_get_shell (display);
  GimpImage        *image     = gimp_display_get_image (display);
  GimpGuide        *guide     = NULL;

  if (gimp_display_shell_get_show_guides (shell) &&
      proximity)
    {
      gint snap_distance = display->config->snap_distance;

      guide = gimp_image_pick_guide (image, coords->x, coords->y,
                                     FUNSCALEX (shell, snap_distance),
                                     FUNSCALEY (shell, snap_distance));
    }

  if (flip->guide != guide ||
      (guide && ! gimp_draw_tool_is_active (draw_tool)))
    {
      gimp_draw_tool_pause (draw_tool);

      if (gimp_draw_tool_is_active (draw_tool) &&
          draw_tool->display != display)
        gimp_draw_tool_stop (draw_tool);

      flip->guide = guide;

      if (! gimp_draw_tool_is_active (draw_tool))
        gimp_draw_tool_start (draw_tool, display);

      gimp_draw_tool_resume (draw_tool);
    }

  gtk_widget_set_sensitive (options->direction_frame, guide == NULL);

  GIMP_TOOL_CLASS (parent_class)->oper_update (tool,
                                               coords, state, proximity,
                                               display);
}
Example #4
0
static void
gimp_color_tool_oper_update (GimpTool         *tool,
                             const GimpCoords *coords,
                             GdkModifierType   state,
                             gboolean          proximity,
                             GimpDisplay      *display)
{
  GimpColorTool    *color_tool   = GIMP_COLOR_TOOL (tool);
  GimpDisplayShell *shell        = gimp_display_get_shell (display);
  GimpImage        *image        = gimp_display_get_image (display);
  GimpSamplePoint  *sample_point = NULL;

  if (color_tool->enabled                               &&
      gimp_display_shell_get_show_sample_points (shell) &&
      proximity)
    {
      gint snap_distance = display->config->snap_distance;

      sample_point =
        gimp_image_find_sample_point (image,
                                      coords->x, coords->y,
                                      FUNSCALEX (shell, snap_distance),
                                      FUNSCALEY (shell, snap_distance));
    }

  if (color_tool->sample_point != sample_point)
    {
      GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);

      gimp_draw_tool_pause (draw_tool);

      if (gimp_draw_tool_is_active (draw_tool) &&
          draw_tool->display != display)
        gimp_draw_tool_stop (draw_tool);

      color_tool->sample_point = sample_point;

      if (! gimp_draw_tool_is_active (draw_tool))
        gimp_draw_tool_start (draw_tool, display);

      gimp_draw_tool_resume (draw_tool);
    }
}
static void
gimp_move_tool_oper_update (GimpTool         *tool,
                            const GimpCoords *coords,
                            GdkModifierType   state,
                            gboolean          proximity,
                            GimpDisplay      *display)
{
  GimpMoveTool     *move    = GIMP_MOVE_TOOL (tool);
  GimpMoveOptions  *options = GIMP_MOVE_TOOL_GET_OPTIONS (tool);
  GimpDisplayShell *shell   = gimp_display_get_shell (display);
  GimpImage        *image   = gimp_display_get_image (display);
  GimpGuide        *guide   = NULL;

  if (options->move_type == GIMP_TRANSFORM_TYPE_LAYER &&
      ! options->move_current                         &&
      gimp_display_shell_get_show_guides (shell)      &&
      proximity)
    {
      const gint snap_distance = display->config->snap_distance;

      guide = gimp_image_find_guide (image, coords->x, coords->y,
                                     FUNSCALEX (shell, snap_distance),
                                     FUNSCALEY (shell, snap_distance));
    }

  if (move->guide != guide)
    {
      GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);

      gimp_draw_tool_pause (draw_tool);

      if (gimp_draw_tool_is_active (draw_tool) &&
          draw_tool->display != display)
        gimp_draw_tool_stop (draw_tool);

      move->guide = guide;

      if (! gimp_draw_tool_is_active (draw_tool))
        gimp_draw_tool_start (draw_tool, display);

      gimp_draw_tool_resume (draw_tool);
    }
}
gboolean
gimp_image_map_tool_on_guide (GimpImageMapTool *im_tool,
                              const GimpCoords *coords,
                              GimpDisplay      *display)
{
  GimpDisplayShell *shell;

  g_return_val_if_fail (GIMP_IS_IMAGE_MAP_TOOL (im_tool), FALSE);
  g_return_val_if_fail (coords != NULL, FALSE);
  g_return_val_if_fail (GIMP_IS_DISPLAY (display), FALSE);

  shell = gimp_display_get_shell (display);

  if (im_tool->image_map     &&
      im_tool->percent_guide &&
      gimp_display_shell_get_show_guides (shell))
    {
      const gint          snap_distance = display->config->snap_distance;
      GimpOrientationType orientation;
      gint                position;

      orientation = gimp_guide_get_orientation (im_tool->percent_guide);
      position    = gimp_guide_get_position (im_tool->percent_guide);

      if (orientation == GIMP_ORIENTATION_HORIZONTAL)
        {
          if (fabs (coords->y - position) <= FUNSCALEY (shell, snap_distance))
            return TRUE;
        }
      else
        {
          if (fabs (coords->x - position) <= FUNSCALEX (shell, snap_distance))
            return TRUE;
        }
    }

  return FALSE;
}
Example #7
0
static void
gimp_color_tool_oper_update (GimpTool        *tool,
                             GimpCoords      *coords,
                             GdkModifierType  state,
                             gboolean         proximity,
                             GimpDisplay     *display)
{
  GimpColorTool    *color_tool   = GIMP_COLOR_TOOL (tool);
  GimpDisplayShell *shell        = GIMP_DISPLAY_SHELL (display->shell);
  GimpSamplePoint  *sample_point = NULL;

  if (color_tool->enabled &&
      gimp_display_shell_get_show_sample_points (shell) && proximity)
    {
      gint snap_distance;

      snap_distance =
        GIMP_DISPLAY_CONFIG (display->image->gimp->config)->snap_distance;

      sample_point =
        gimp_image_find_sample_point (display->image,
                                      coords->x, coords->y,
                                      FUNSCALEX (shell, snap_distance),
                                      FUNSCALEY (shell, snap_distance));
    }

  if (color_tool->sample_point && color_tool->sample_point != sample_point)
    gimp_image_update_sample_point (shell->display->image,
                                    color_tool->sample_point);

  color_tool->sample_point = sample_point;

  if (color_tool->sample_point)
    gimp_display_shell_draw_sample_point (shell, color_tool->sample_point,
                                          TRUE);
}
static void
gimp_move_tool_cursor_update (GimpTool         *tool,
                              const GimpCoords *coords,
                              GdkModifierType   state,
                              GimpDisplay      *display)
{
  GimpMoveOptions    *options     = GIMP_MOVE_TOOL_GET_OPTIONS (tool);
  GimpDisplayShell   *shell       = gimp_display_get_shell (display);
  GimpImage          *image       = gimp_display_get_image (display);
  GimpCursorType      cursor      = GIMP_CURSOR_MOUSE;
  GimpToolCursorType  tool_cursor = GIMP_TOOL_CURSOR_MOVE;
  GimpCursorModifier  modifier    = GIMP_CURSOR_MODIFIER_NONE;

  if (options->move_type == GIMP_TRANSFORM_TYPE_PATH)
    {
      tool_cursor = GIMP_TOOL_CURSOR_PATHS;
      modifier    = GIMP_CURSOR_MODIFIER_MOVE;

      if (options->move_current)
        {
          if (! gimp_image_get_active_vectors (image))
            modifier = GIMP_CURSOR_MODIFIER_BAD;
        }
      else
        {
          if (gimp_draw_tool_on_vectors (GIMP_DRAW_TOOL (tool), display,
                                         coords, 7, 7,
                                         NULL, NULL, NULL, NULL, NULL, NULL))
            {
              tool_cursor = GIMP_TOOL_CURSOR_HAND;
            }
          else
            {
              modifier = GIMP_CURSOR_MODIFIER_BAD;
            }
        }
    }
  else if (options->move_type == GIMP_TRANSFORM_TYPE_SELECTION)
    {
      tool_cursor = GIMP_TOOL_CURSOR_RECT_SELECT;
      modifier    = GIMP_CURSOR_MODIFIER_MOVE;

      if (gimp_channel_is_empty (gimp_image_get_mask (image)))
        modifier = GIMP_CURSOR_MODIFIER_BAD;
    }
  else if (options->move_current)
    {
      if (! gimp_image_get_active_drawable (image))
        modifier = GIMP_CURSOR_MODIFIER_BAD;
    }
  else
    {
      GimpGuide  *guide;
      GimpLayer  *layer;
      const gint  snap_distance = display->config->snap_distance;

      if (gimp_display_shell_get_show_guides (shell) &&
          (guide = gimp_image_find_guide (image, coords->x, coords->y,
                                          FUNSCALEX (shell, snap_distance),
                                          FUNSCALEY (shell, snap_distance))))
        {
          tool_cursor = GIMP_TOOL_CURSOR_HAND;
          modifier    = GIMP_CURSOR_MODIFIER_MOVE;
        }
      else if ((layer = gimp_image_pick_layer (image,
                                               coords->x, coords->y)))
        {
          /*  if there is a floating selection, and this aint it...  */
          if (gimp_image_get_floating_selection (image) &&
              ! gimp_layer_is_floating_sel (layer))
            {
              tool_cursor = GIMP_TOOL_CURSOR_MOVE;
              modifier    = GIMP_CURSOR_MODIFIER_ANCHOR;
            }
          else if (layer != gimp_image_get_active_layer (image))
            {
              tool_cursor = GIMP_TOOL_CURSOR_HAND;
              modifier    = GIMP_CURSOR_MODIFIER_MOVE;
            }
        }
      else
        {
          modifier = GIMP_CURSOR_MODIFIER_BAD;
        }
    }

  gimp_tool_control_set_cursor          (tool->control, cursor);
  gimp_tool_control_set_tool_cursor     (tool->control, tool_cursor);
  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
static void
gimp_move_tool_button_press (GimpTool            *tool,
                             const GimpCoords    *coords,
                             guint32              time,
                             GdkModifierType      state,
                             GimpButtonPressType  press_type,
                             GimpDisplay         *display)
{
  GimpMoveTool     *move    = GIMP_MOVE_TOOL (tool);
  GimpMoveOptions  *options = GIMP_MOVE_TOOL_GET_OPTIONS (tool);
  GimpDisplayShell *shell   = gimp_display_get_shell (display);
  GimpImage        *image   = gimp_display_get_image (display);

  tool->display = display;

  move->floating_layer     = NULL;
  move->guide              = NULL;
  move->moving_guide       = FALSE;
  move->old_active_layer   = NULL;
  move->old_active_vectors = NULL;

  if (! options->move_current)
    {
      if (options->move_type == GIMP_TRANSFORM_TYPE_PATH)
        {
          GimpVectors *vectors;

          if (gimp_draw_tool_on_vectors (GIMP_DRAW_TOOL (tool), display,
                                         coords, 7, 7,
                                         NULL, NULL, NULL, NULL, NULL,
                                         &vectors))
            {
              move->old_active_vectors =
                gimp_image_get_active_vectors (image);

              gimp_image_set_active_vectors (image, vectors);
            }
          else
            {
              /*  no path picked  */
              return;
            }
        }
      else if (options->move_type == GIMP_TRANSFORM_TYPE_LAYER)
        {
          GimpGuide  *guide;
          GimpLayer  *layer;
          const gint  snap_distance = display->config->snap_distance;

          if (gimp_display_shell_get_show_guides (shell) &&
              (guide = gimp_image_find_guide (image,
                                              coords->x, coords->y,
                                              FUNSCALEX (shell, snap_distance),
                                              FUNSCALEY (shell, snap_distance))))
            {
              move->guide             = guide;
              move->moving_guide      = TRUE;
              move->guide_position    = gimp_guide_get_position (guide);
              move->guide_orientation = gimp_guide_get_orientation (guide);

              gimp_tool_control_set_scroll_lock (tool->control, TRUE);
              gimp_tool_control_set_precision   (tool->control,
                                                 GIMP_CURSOR_PRECISION_PIXEL_BORDER);

              gimp_tool_control_activate (tool->control);

              gimp_display_shell_selection_pause (shell);

              gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display);

              gimp_tool_push_status_length (tool, display,
                                            _("Move Guide: "),
                                            SWAP_ORIENT (move->guide_orientation),
                                            move->guide_position,
                                            NULL);

              return;
            }
          else if ((layer = gimp_image_pick_layer (image,
                                                   coords->x,
                                                   coords->y)))
            {
              if (gimp_image_get_floating_selection (image) &&
                  ! gimp_layer_is_floating_sel (layer))
                {
                  /*  If there is a floating selection, and this aint it,
                   *  use the move tool to anchor it.
                   */
                  move->floating_layer =
                    gimp_image_get_floating_selection (image);

                  gimp_tool_control_activate (tool->control);

                  return;
                }
              else
                {
                  move->old_active_layer = gimp_image_get_active_layer (image);

                  gimp_image_set_active_layer (image, layer);
                }
            }
          else
            {
              /*  no guide and no layer picked  */

              return;
            }
        }
    }

  switch (options->move_type)
    {
    case GIMP_TRANSFORM_TYPE_PATH:
      if (gimp_image_get_active_vectors (image))
        gimp_edit_selection_tool_start (tool, display, coords,
                                        GIMP_TRANSLATE_MODE_VECTORS, TRUE);
      break;

    case GIMP_TRANSFORM_TYPE_SELECTION:
      if (! gimp_channel_is_empty (gimp_image_get_mask (image)))
        gimp_edit_selection_tool_start (tool, display, coords,
                                        GIMP_TRANSLATE_MODE_MASK, TRUE);
      break;

    case GIMP_TRANSFORM_TYPE_LAYER:
      {
        GimpDrawable *drawable = gimp_image_get_active_drawable (image);

        if (GIMP_IS_LAYER_MASK (drawable))
          gimp_edit_selection_tool_start (tool, display, coords,
                                          GIMP_TRANSLATE_MODE_LAYER_MASK, TRUE);
        else if (GIMP_IS_CHANNEL (drawable))
          gimp_edit_selection_tool_start (tool, display, coords,
                                          GIMP_TRANSLATE_MODE_CHANNEL, TRUE);
        else if (GIMP_IS_LAYER (drawable))
          gimp_edit_selection_tool_start (tool, display, coords,
                                          GIMP_TRANSLATE_MODE_LAYER, TRUE);
      }
      break;
    }
}
Example #10
0
/* some rather complex logic here.  If the user clicks without modifiers,
 * then we start a new list, and use the first object in it as reference.
 * If the user clicks using Shift, or draws a rubber-band box, then
 * we add objects to the list, but do not specify which one should
 * be used as reference.
 */
static void
gimp_align_tool_button_release (GimpTool              *tool,
                                const GimpCoords      *coords,
                                guint32                time,
                                GdkModifierType        state,
                                GimpButtonReleaseType  release_type,
                                GimpDisplay           *display)
{
    GimpAlignTool    *align_tool = GIMP_ALIGN_TOOL (tool);
    GimpAlignOptions *options    = GIMP_ALIGN_TOOL_GET_OPTIONS (tool);
    GimpDisplayShell *shell      = gimp_display_get_shell (display);
    GObject          *object     = NULL;
    GimpImage        *image      = gimp_display_get_image (display);
    GdkModifierType   extend_mask;
    gint              i;

    extend_mask = gimp_get_extend_selection_mask ();

    gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));

    gimp_tool_control_halt (tool->control);

    if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
    {
        align_tool->x2 = align_tool->x1;
        align_tool->y2 = align_tool->y1;

        gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
        return;
    }

    if (! (state & extend_mask)) /* start a new list */
    {
        gimp_align_tool_clear_selected (align_tool);
        align_tool->set_reference = FALSE;
    }

    /* if mouse has moved less than EPSILON pixels since button press,
     * select the nearest thing, otherwise make a rubber-band rectangle
     */
    if (hypot (coords->x - align_tool->x1,
               coords->y - align_tool->y1) < EPSILON)
    {
        GimpVectors *vectors;
        GimpGuide   *guide;
        GimpLayer   *layer;
        gint         snap_distance = display->config->snap_distance;

        if (gimp_draw_tool_on_vectors (GIMP_DRAW_TOOL (tool), display,
                                       coords, snap_distance, snap_distance,
                                       NULL, NULL, NULL, NULL, NULL,
                                       &vectors))
        {
            object = G_OBJECT (vectors);
        }
        else if (gimp_display_shell_get_show_guides (shell) &&
                 (guide = gimp_image_find_guide (image,
                          coords->x, coords->y,
                          FUNSCALEX (shell, snap_distance),
                          FUNSCALEY (shell, snap_distance))))
        {
            object = G_OBJECT (guide);
        }
        else
        {
            if ((layer = gimp_image_pick_layer_by_bounds (image,
                         coords->x, coords->y)))
            {
                object = G_OBJECT (layer);
            }
        }

        if (object)
        {
            if (! g_list_find (align_tool->selected_objects, object))
            {
                align_tool->selected_objects =
                    g_list_append (align_tool->selected_objects, object);

                g_signal_connect (object, "removed",
                                  G_CALLBACK (gimp_align_tool_object_removed),
                                  align_tool);

                /* if an object has been selected using unmodified click,
                 * it should be used as the reference
                 */
                if (! (state & extend_mask))
                    align_tool->set_reference = TRUE;
            }
        }
    }
    else  /* FIXME: look for vectors too */
    {
        gint   X0 = MIN (coords->x, align_tool->x1);
        gint   X1 = MAX (coords->x, align_tool->x1);
        gint   Y0 = MIN (coords->y, align_tool->y1);
        gint   Y1 = MAX (coords->y, align_tool->y1);
        GList *all_layers;
        GList *list;

        all_layers = gimp_image_get_layer_list (image);

        for (list = all_layers; list; list = g_list_next (list))
        {
            GimpLayer *layer = list->data;
            gint       x0, y0, x1, y1;

            if (! gimp_item_get_visible (GIMP_ITEM (layer)))
                continue;

            gimp_item_get_offset (GIMP_ITEM (layer), &x0, &y0);
            x1 = x0 + gimp_item_get_width  (GIMP_ITEM (layer));
            y1 = y0 + gimp_item_get_height (GIMP_ITEM (layer));

            if (x0 < X0 || y0 < Y0 || x1 > X1 || y1 > Y1)
                continue;

            if (g_list_find (align_tool->selected_objects, layer))
                continue;

            align_tool->selected_objects =
                g_list_append (align_tool->selected_objects, layer);

            g_signal_connect (layer, "removed",
                              G_CALLBACK (gimp_align_tool_object_removed),
                              align_tool);
        }

        g_list_free (all_layers);
    }

    for (i = 0; i < ALIGN_OPTIONS_N_BUTTONS; i++)
    {
        if (options->button[i])
            gtk_widget_set_sensitive (options->button[i],
                                      align_tool->selected_objects != NULL);
    }

    align_tool->x2 = align_tool->x1;
    align_tool->y2 = align_tool->y1;

    gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
/**
 * gimp_display_shell_scale_to_rectangle:
 * @shell:         the #GimpDisplayShell
 * @zoom_type:     whether to zoom in or out
 * @x:             retangle's x in image coordinates
 * @y:             retangle's y in image coordinates
 * @width:         retangle's width in image coordinates
 * @height:        retangle's height in image coordinates
 * @resize_window: whether the display window should be resized
 *
 * Scales and scrolls to a specific image rectangle
 **/
void
gimp_display_shell_scale_to_rectangle (GimpDisplayShell *shell,
                                       GimpZoomType      zoom_type,
                                       gdouble           x,
                                       gdouble           y,
                                       gdouble           width,
                                       gdouble           height,
                                       gboolean          resize_window)
{
  GimpImage *image;
  gdouble    current_scale;
  gdouble    new_scale;
  gdouble    display_width;
  gdouble    display_height;
  gdouble    factor   = 1.0;
  gint       offset_x = 0;
  gint       offset_y = 0;
  gdouble    xres;
  gdouble    yres;
  gdouble    screen_xres;
  gdouble    screen_yres;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  image = gimp_display_get_image (shell->display);

  width  = MAX (1.0, width);
  height = MAX (1.0, height);

  current_scale = gimp_zoom_model_get_factor (shell->zoom);

  display_width  = FUNSCALEX (shell, shell->disp_width);
  display_height = FUNSCALEY (shell, shell->disp_height);

  switch (zoom_type)
    {
    case GIMP_ZOOM_IN:
      factor = MIN ((display_width  / width),
                    (display_height / height));
      break;

    case GIMP_ZOOM_OUT:
      factor = MAX ((width  / display_width),
                    (height / display_height));
      break;

    default:
      g_return_if_reached ();
      break;
    }

  new_scale = current_scale * factor;

  gimp_image_get_resolution (image, &xres, &yres);
  gimp_display_shell_scale_get_screen_resolution (shell,
                                                  &screen_xres, &screen_yres);

  switch (zoom_type)
    {
    case GIMP_ZOOM_IN:
      /*  move the center of the rectangle to the center of the
       *  viewport:
       *
       *  new_offset = center of rectangle in new scale screen coords
       *               including offset
       *               -
       *               center of viewport in screen coords without
       *               offset
       */
      offset_x = RINT (new_scale * (x + width / 2.0) *
                       screen_xres / xres -
                       (shell->disp_width / 2.0));

      offset_y = RINT (new_scale * (y + height / 2.0) *
                       screen_yres / yres -
                       (shell->disp_height / 2.0));
      break;

    case GIMP_ZOOM_OUT:
      /*  move the center of the viewport to the center of the
       *  rectangle:
       *
       *  new_offset = center of viewport in new scale screen coords
       *               including offset
       *               -
       *               center of rectangle in screen coords without
       *               offset
       */
      offset_x = RINT (new_scale * UNSCALEX (shell,
                                             shell->offset_x +
                                             shell->disp_width / 2.0) *
                       screen_xres / xres -
                       (SCALEX (shell, x + width / 2.0) -
                        shell->offset_x));

      offset_y = RINT (new_scale * UNSCALEY (shell,
                                             shell->offset_y +
                                             shell->disp_height / 2.0) *
                       screen_yres / yres -
                       (SCALEY (shell, y + height / 2.0) -
                        shell->offset_y));
      break;

    default:
      break;
    }

  if (new_scale != current_scale   ||
      offset_x  != shell->offset_x ||
      offset_y  != shell->offset_y)
    {
      gimp_display_shell_scale_by_values (shell,
                                          new_scale,
                                          offset_x, offset_y,
                                          resize_window);
    }
}
/**
 * gimp_display_shell_scale_update_rulers:
 * @shell:
 *
 **/
void
gimp_display_shell_scale_update_rulers (GimpDisplayShell *shell)
{
  GimpImage *image;
  gint       image_width;
  gint       image_height;
  gdouble    resolution_x = 1.0;
  gdouble    resolution_y = 1.0;
  gdouble    horizontal_lower;
  gdouble    horizontal_upper;
  gdouble    horizontal_max_size;
  gdouble    vertical_lower;
  gdouble    vertical_upper;
  gdouble    vertical_max_size;

  if (! shell->display)
    return;

  image = gimp_display_get_image (shell->display);

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

      gimp_image_get_resolution (image, &resolution_x, &resolution_y);
    }
  else
    {
      image_width  = shell->disp_width;
      image_height = shell->disp_height;
    }


  /* Initialize values */

  horizontal_lower = 0;
  vertical_lower   = 0;

  if (image)
    {
      horizontal_upper    = gimp_pixels_to_units (FUNSCALEX (shell,
                                                             shell->disp_width),
                                                  shell->unit,
                                                  resolution_x);
      horizontal_max_size = gimp_pixels_to_units (MAX (image_width,
                                                       image_height),
                                                  shell->unit,
                                                  resolution_x);

      vertical_upper      = gimp_pixels_to_units (FUNSCALEY (shell,
                                                             shell->disp_height),
                                                  shell->unit,
                                                  resolution_y);
      vertical_max_size   = gimp_pixels_to_units (MAX (image_width,
                                                       image_height),
                                                  shell->unit,
                                                  resolution_y);
    }
  else
    {
      horizontal_upper    = image_width;
      horizontal_max_size = MAX (image_width, image_height);

      vertical_upper      = image_height;
      vertical_max_size   = MAX (image_width, image_height);
    }


  /* Adjust due to scrolling */

  if (image)
    {
      gdouble offset_x;
      gdouble offset_y;

      offset_x = gimp_pixels_to_units (FUNSCALEX (shell,
                                                  (gdouble) shell->offset_x),
                                       shell->unit,
                                       resolution_x);

      offset_y = gimp_pixels_to_units (FUNSCALEX (shell,
                                                  (gdouble) shell->offset_y),
                                       shell->unit,
                                       resolution_y);

      horizontal_lower += offset_x;
      horizontal_upper += offset_x;

      vertical_lower   += offset_y;
      vertical_upper   += offset_y;
    }

  /* Finally setup the actual rulers */

  gimp_ruler_set_range (GIMP_RULER (shell->hrule),
                        horizontal_lower,
                        horizontal_upper,
                        horizontal_max_size);

  gimp_ruler_set_unit  (GIMP_RULER (shell->hrule),
                        shell->unit);

  gimp_ruler_set_range (GIMP_RULER (shell->vrule),
                        vertical_lower,
                        vertical_upper,
                        vertical_max_size);

  gimp_ruler_set_unit  (GIMP_RULER (shell->vrule),
                        shell->unit);
}
Example #13
0
/*
 * some rather complex logic here.  If the user clicks without modifiers,
 * then we start a new list, and use the first object in it as reference.
 * If the user clicks using Shift, or draws a rubber-band box, then
 * we add objects to the list, but do not specify which one should
 * be used as reference.
 */
static void
gimp_align_tool_button_release (GimpTool              *tool,
                                GimpCoords            *coords,
                                guint32                time,
                                GdkModifierType        state,
                                GimpButtonReleaseType  release_type,
                                GimpDisplay           *display)
{
  GimpAlignTool    *align_tool = GIMP_ALIGN_TOOL (tool);
  GimpDisplayShell *shell      = GIMP_DISPLAY_SHELL (display->shell);
  GObject          *object     = NULL;
  GimpImage        *image      = display->image;
  gint              i;

  gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));

  if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
    {
      align_tool->x1 = align_tool->x0;
      align_tool->y1 = align_tool->y0;

      gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
      return;
    }

  if (! (state & GDK_SHIFT_MASK)) /* start a new list */
    {
      clear_all_selected_objects (align_tool);
      align_tool->set_reference = FALSE;
    }

  /* if mouse has moved less than EPSILON pixels since button press, select
     the nearest thing, otherwise make a rubber-band rectangle */
  if (hypot (coords->x - align_tool->x0, coords->y - align_tool->y0) < EPSILON)
    {
      GimpVectors *vectors;
      GimpGuide   *guide;
      GimpLayer   *layer;
      gint         snap_distance;

      snap_distance =
        GIMP_DISPLAY_CONFIG (display->image->gimp->config)->snap_distance;

      if (gimp_draw_tool_on_vectors (GIMP_DRAW_TOOL (tool), display,
                                     coords, snap_distance, snap_distance,
                                     NULL, NULL, NULL, NULL, NULL,
                                     &vectors))
        {
          object = G_OBJECT (vectors);
        }
      else if (gimp_display_shell_get_show_guides (shell) &&
               (guide = gimp_image_find_guide (display->image,
                                               coords->x, coords->y,
                                               FUNSCALEX (shell, snap_distance),
                                               FUNSCALEY (shell, snap_distance))))
        {
          object = G_OBJECT (guide);
        }
      else
        {
          if ((layer = select_layer_by_coords (display->image,
                                               coords->x, coords->y)))
            {
              object = G_OBJECT (layer);
            }
        }

      if (object)
        {
          if (! g_list_find (align_tool->selected_objects, object))
            {
              align_tool->selected_objects
                = g_list_append (align_tool->selected_objects, object);
              g_signal_connect (object, "removed",
                                G_CALLBACK (clear_selected_object),
                                (gpointer) align_tool);

              /* if an object has been selected using unmodified click,
               * it should be used as the reference
               */
              if (! (state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)))
                align_tool->set_reference = TRUE;
            }
        }
    }
  else  /* FIXME: look for vectors too */
    {
      gint   X0    = MIN (coords->x, align_tool->x0);
      gint   X1    = MAX (coords->x, align_tool->x0);
      gint   Y0    = MIN (coords->y, align_tool->y0);
      gint   Y1    = MAX (coords->y, align_tool->y0);
      GList *list;

      for (list = GIMP_LIST (image->layers)->list;
           list;
           list = g_list_next (list))
        {
          GimpLayer *layer = list->data;
          gint       x0, y0, x1, y1;

          if (! gimp_item_get_visible (GIMP_ITEM (layer)))
            continue;

          gimp_item_offsets (GIMP_ITEM (layer), &x0, &y0);
          x1 = x0 + gimp_item_width (GIMP_ITEM (layer));
          y1 = y0 + gimp_item_height (GIMP_ITEM (layer));

          if (x0 < X0 || y0 < Y0 || x1 > X1 || y1 > Y1)
            continue;

          if (g_list_find (align_tool->selected_objects, layer))
            continue;

          align_tool->selected_objects
            = g_list_append (align_tool->selected_objects, layer);
          g_signal_connect (layer, "removed", G_CALLBACK (clear_selected_object),
                            (gpointer) align_tool);
        }
    }

  for (i = 0; i < ALIGN_TOOL_NUM_BUTTONS; i++)
    gtk_widget_set_sensitive (align_tool->button[i],
                              (align_tool->selected_objects != NULL));

  align_tool->x1 = align_tool->x0;
  align_tool->y1 = align_tool->y0;

  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}