示例#1
0
文件: gimpcagetool.c 项目: STRNG/gimp
static void
gimp_cage_tool_cursor_update (GimpTool         *tool,
                              const GimpCoords *coords,
                              GdkModifierType   state,
                              GimpDisplay      *display)
{
  GimpCageTool       *ct       = GIMP_CAGE_TOOL (tool);
  GimpCageOptions    *options  = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
  GimpCursorModifier  modifier = GIMP_CURSOR_MODIFIER_PLUS;

  if (tool->display)
    {
      if (ct->hovering_handle != -1)
        {
          modifier = GIMP_CURSOR_MODIFIER_MOVE;
        }
      else if (ct->hovering_edge != -1 && options->cage_mode == GIMP_CAGE_MODE_CAGE_CHANGE)
        {
          modifier = GIMP_CURSOR_MODIFIER_PLUS;
        }
      else
        {
          if (gimp_cage_tool_is_complete (ct))
            modifier = GIMP_CURSOR_MODIFIER_BAD;
        }
    }

  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
示例#2
0
文件: gimpcagetool.c 项目: STRNG/gimp
static void
gimp_cage_tool_motion (GimpTool         *tool,
                       const GimpCoords *coords,
                       guint32           time,
                       GdkModifierType   state,
                       GimpDisplay      *display)
{
  GimpCageTool    *ct       = GIMP_CAGE_TOOL (tool);
  GimpCageOptions *options  = GIMP_CAGE_TOOL_GET_OPTIONS (ct);

  gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));

  ct->cursor_x = coords->x;
  ct->cursor_y = coords->y;

  switch (ct->tool_state)
    {
    case CAGE_STATE_MOVE_HANDLE:
    case CAGE_STATE_CLOSING:
    case DEFORM_STATE_MOVE_HANDLE:
      gimp_cage_config_add_displacement (ct->config,
                                         options->cage_mode,
                                         ct->cursor_x - ct->movement_start_x,
                                         ct->cursor_y - ct->movement_start_y);
      break;
    }

  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
示例#3
0
static void
gimp_cage_tool_create_render_node (GimpCageTool *ct)
{
    GimpCageOptions *options  = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
    GeglNode        *coef, *cage, *render; /* Render nodes */
    GeglNode        *input, *output; /* Proxy nodes*/
    GeglNode        *node; /* wraper to be returned */
    GObject         *transform;

    g_return_if_fail (ct->render_node == NULL);
    /* render_node is not supposed to be recreated */

    node = gegl_node_new ();

    input  = gegl_node_get_input_proxy  (node, "input");
    output = gegl_node_get_output_proxy (node, "output");

    coef = gegl_node_new_child (node,
                                "operation", "gegl:buffer-source",
                                "buffer",    ct->coef,
                                NULL);

    cage = gegl_node_new_child (node,
                                "operation",        "gimp:cage-transform",
                                "config",           ct->config,
                                "fill_plain_color", options->fill_plain_color,
                                NULL);

    render = gegl_node_new_child (node,
                                  "operation", "gegl:map-absolute",
                                  NULL);

    gegl_node_connect_to (input, "output",
                          cage, "input");

    gegl_node_connect_to (coef, "output",
                          cage, "aux");

    gegl_node_connect_to (input, "output",
                          render, "input");

    gegl_node_connect_to (cage, "output",
                          render, "aux");

    gegl_node_connect_to (render, "output",
                          output, "input");

    ct->render_node = node;
    ct->cage_node = cage;
    ct->coef_node = coef;

    g_object_get (cage, "gegl-operation", &transform, NULL);
    g_signal_connect (transform, "notify::progress",
                      G_CALLBACK (gimp_cage_tool_transform_progress),
                      ct);
    g_object_unref (transform);
}
示例#4
0
文件: gimpcagetool.c 项目: STRNG/gimp
static gint
gimp_cage_tool_is_on_edge (GimpCageTool *ct,
                           gdouble       x,
                           gdouble       y,
                           gint          handle_size)
{
  GimpCageOptions *options = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
  GimpCageConfig  *config  = ct->config;
  gint             i;
  guint            n_cage_vertices;
  GimpVector2      A, B, C, AB, BC, AC;
  gdouble          lAB, lBC, lAC, lEB, lEC;

  g_return_val_if_fail (GIMP_IS_CAGE_TOOL (ct), -1);

  n_cage_vertices = gimp_cage_config_get_n_points (config);

  if (n_cage_vertices < 2)
    return -1;

  A = gimp_cage_config_get_point_coordinate (config,
                                             options->cage_mode,
                                             n_cage_vertices-1);
  B = gimp_cage_config_get_point_coordinate (config,
                                             options->cage_mode,
                                             0);
  C.x = x;
  C.y = y;

  for (i = 0; i < n_cage_vertices; i++)
    {
      gimp_vector2_sub (&AB, &A, &B);
      gimp_vector2_sub (&BC, &B, &C);
      gimp_vector2_sub (&AC, &A, &C);

      lAB = gimp_vector2_length (&AB);
      lBC = gimp_vector2_length (&BC);
      lAC = gimp_vector2_length (&AC);
      lEB = lAB / 2 + (SQR (lBC) - SQR (lAC)) / (2 * lAB);
      lEC = sqrt (SQR (lBC) - SQR (lEB));

      if ((lEC < handle_size / 2) && (abs (SQR (lBC) - SQR (lAC)) <= SQR (lAB)))
        return i;

      A = B;
      B = gimp_cage_config_get_point_coordinate (config,
                                                 options->cage_mode,
                                                 (i+1) % n_cage_vertices);
    }

  return -1;
}
示例#5
0
文件: gimpcagetool.c 项目: STRNG/gimp
static gint
gimp_cage_tool_is_on_handle (GimpCageTool *ct,
                             GimpDrawTool *draw_tool,
                             GimpDisplay  *display,
                             gdouble       x,
                             gdouble       y,
                             gint          handle_size)
{
  GimpCageOptions *options = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
  GimpCageConfig  *config  = ct->config;
  gdouble          dist    = G_MAXDOUBLE;
  gint             i;
  GimpVector2      cage_point;
  guint            n_cage_vertices;

  g_return_val_if_fail (GIMP_IS_CAGE_TOOL (ct), -1);

  n_cage_vertices = gimp_cage_config_get_n_points (config);

  if (n_cage_vertices == 0)
    return -1;

  for (i = 0; i < n_cage_vertices; i++)
    {
      cage_point = gimp_cage_config_get_point_coordinate (config,
                                                          options->cage_mode,
                                                          i);
      cage_point.x += ct->offset_x;
      cage_point.y += ct->offset_y;

      dist = gimp_draw_tool_calc_distance_square (GIMP_DRAW_TOOL (draw_tool),
                                                  display,
                                                  x, y,
                                                  cage_point.x,
                                                  cage_point.y);

      if (dist <= SQR (handle_size / 2))
        return i;
    }

  return -1;
}
示例#6
0
文件: gimpcagetool.c 项目: STRNG/gimp
static void
gimp_cage_tool_render_node_update (GimpCageTool *ct)
{
  GimpCageOptions *options  = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
  gboolean         option_fill, node_fill;
  GeglBuffer      *buffer;

  g_object_get (options,
                "fill-plain-color", &option_fill,
                NULL);

  gegl_node_get (ct->cage_node,
                 "fill-plain-color", &node_fill,
                 NULL);

  if (option_fill != node_fill)
    {
      gegl_node_set (ct->cage_node,
                     "fill_plain_color", option_fill,
                     NULL);
    }

  gegl_node_get (ct->coef_node,
                 "buffer", &buffer,
                 NULL);

  if (buffer != ct->coef)
    {
      gegl_node_set (ct->coef_node,
                     "buffer",  ct->coef,
                     NULL);
    }

  /* This just unref buffer, since gegl_node_get add a refcount on it */
  if (buffer)
    {
      g_object_unref (buffer);
    }
}
示例#7
0
文件: gimpcagetool.c 项目: STRNG/gimp
static void
gimp_cage_tool_draw (GimpDrawTool *draw_tool)
{
  GimpCageTool    *ct        = GIMP_CAGE_TOOL (draw_tool);
  GimpCageOptions *options   = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
  GimpCageConfig  *config    = ct->config;
  GimpCanvasGroup *stroke_group;
  gint             n_vertices;
  gint             i;
  GimpHandleType   handle;

  n_vertices = gimp_cage_config_get_n_points (config);

  if (n_vertices == 0)
    return;

  if (ct->tool_state == CAGE_STATE_INIT)
    return;

  stroke_group = gimp_draw_tool_add_stroke_group (draw_tool);

  gimp_draw_tool_push_group (draw_tool, stroke_group);

  /* If needed, draw line to the cursor. */
  if (! gimp_cage_tool_is_complete (ct))
    {
      GimpVector2 last_point;

      last_point = gimp_cage_config_get_point_coordinate (ct->config,
                                                          options->cage_mode,
                                                          n_vertices - 1);

      gimp_draw_tool_add_line (draw_tool,
                               last_point.x + ct->offset_x,
                               last_point.y + ct->offset_y,
                               ct->cursor_x,
                               ct->cursor_y);
    }

  gimp_draw_tool_pop_group (draw_tool);

  /* Draw the cage with handles. */
  for (i = 0; i < n_vertices; i++)
    {
      GimpVector2 point1, point2;

      point1 = gimp_cage_config_get_point_coordinate (ct->config,
                                                      options->cage_mode,
                                                      i);
      point1.x += ct->offset_x;
      point1.y += ct->offset_y;

      if (i > 0 || gimp_cage_tool_is_complete (ct))
        {
          gint index_point2;

          if (i == 0)
            index_point2 = n_vertices - 1;
          else
            index_point2 = i - 1;

          point2 = gimp_cage_config_get_point_coordinate (ct->config,
                                                          options->cage_mode,
                                                          index_point2);
          point2.x += ct->offset_x;
          point2.y += ct->offset_y;

          gimp_draw_tool_push_group (draw_tool, stroke_group);

          gimp_draw_tool_add_line (draw_tool,
                                   point1.x,
                                   point1.y,
                                   point2.x,
                                   point2.y);

          gimp_draw_tool_pop_group (draw_tool);
        }

      if (i == ct->hovering_handle)
        handle = GIMP_HANDLE_FILLED_CIRCLE;
      else
        handle = GIMP_HANDLE_CIRCLE;

      gimp_draw_tool_add_handle (draw_tool,
                                 handle,
                                 point1.x,
                                 point1.y,
                                 GIMP_TOOL_HANDLE_SIZE_CIRCLE,
                                 GIMP_TOOL_HANDLE_SIZE_CIRCLE,
                                 GIMP_HANDLE_ANCHOR_CENTER);

      if (gimp_cage_config_point_is_selected (ct->config, i))
        {
          gimp_draw_tool_add_handle (draw_tool,
                                     GIMP_HANDLE_SQUARE,
                                     point1.x,
                                     point1.y,
                                     GIMP_TOOL_HANDLE_SIZE_CIRCLE,
                                     GIMP_TOOL_HANDLE_SIZE_CIRCLE,
                                     GIMP_HANDLE_ANCHOR_CENTER);
        }
    }

  if (ct->tool_state == DEFORM_STATE_SELECTING ||
      ct->tool_state == CAGE_STATE_SELECTING)
    {
      gimp_draw_tool_add_rectangle (draw_tool,
                                    FALSE,
                                    MIN (ct->selection_start_x, ct->cursor_x),
                                    MIN (ct->selection_start_y, ct->cursor_y),
                                    abs (ct->selection_start_x - ct->cursor_x),
                                    abs (ct->selection_start_y - ct->cursor_y));
    }
}
示例#8
0
文件: gimpcagetool.c 项目: STRNG/gimp
void
gimp_cage_tool_button_release (GimpTool              *tool,
                               const GimpCoords      *coords,
                               guint32                time,
                               GdkModifierType        state,
                               GimpButtonReleaseType  release_type,
                               GimpDisplay           *display)
{
  GimpCageTool    *ct      = GIMP_CAGE_TOOL (tool);
  GimpCageOptions *options = GIMP_CAGE_TOOL_GET_OPTIONS (ct);

  gimp_draw_tool_pause (GIMP_DRAW_TOOL (ct));

  gimp_tool_control_halt (tool->control);

  if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
    {
      /* Cancelling */

      switch (ct->tool_state)
        {
        case CAGE_STATE_CLOSING:
          ct->tool_state = CAGE_STATE_WAIT;
          break;

        case CAGE_STATE_MOVE_HANDLE:
          gimp_cage_config_remove_last_cage_point (ct->config);
          ct->tool_state = CAGE_STATE_WAIT;
          break;

        case CAGE_STATE_SELECTING:
          ct->tool_state = CAGE_STATE_WAIT;
          break;

        case DEFORM_STATE_MOVE_HANDLE:
          gimp_cage_tool_image_map_update (ct);
          ct->tool_state = DEFORM_STATE_WAIT;
          break;

        case DEFORM_STATE_SELECTING:
          ct->tool_state = DEFORM_STATE_WAIT;
          break;
        }

      gimp_cage_config_reset_displacement (ct->config);
    }
  else
    {
      /* Normal release */

      switch (ct->tool_state)
        {
        case CAGE_STATE_CLOSING:
          ct->dirty_coef = TRUE;
          gimp_cage_config_commit_displacement (ct->config);

          if (release_type == GIMP_BUTTON_RELEASE_CLICK)
            g_object_set (options, "cage-mode", GIMP_CAGE_MODE_DEFORM, NULL);
          break;

        case CAGE_STATE_MOVE_HANDLE:
          ct->dirty_coef = TRUE;
          ct->tool_state = CAGE_STATE_WAIT;
          gimp_cage_config_commit_displacement (ct->config);
          break;

        case CAGE_STATE_SELECTING:
          {
            GeglRectangle area = { MIN (ct->selection_start_x, coords->x) - ct->offset_x,
                                   MIN (ct->selection_start_y, coords->y) - ct->offset_y,
                                   abs (ct->selection_start_x - coords->x),
                                   abs (ct->selection_start_y - coords->y) };

            if (state & GDK_SHIFT_MASK)
              {
                gimp_cage_config_select_add_area (ct->config,
                                                  GIMP_CAGE_MODE_CAGE_CHANGE,
                                                  area);
              }
            else
              {
                gimp_cage_config_select_area (ct->config,
                                              GIMP_CAGE_MODE_CAGE_CHANGE,
                                              area);
              }

            ct->tool_state = CAGE_STATE_WAIT;
          }
          break;

        case DEFORM_STATE_MOVE_HANDLE:
          ct->tool_state = DEFORM_STATE_WAIT;
          gimp_cage_config_commit_displacement (ct->config);
          gimp_cage_tool_image_map_update (ct);
          break;

        case DEFORM_STATE_SELECTING:
          {
            GeglRectangle area = { MIN (ct->selection_start_x, coords->x) - ct->offset_x,
                                   MIN (ct->selection_start_y, coords->y) - ct->offset_y,
                                   abs (ct->selection_start_x - coords->x),
                                   abs (ct->selection_start_y - coords->y) };

            if (state & GDK_SHIFT_MASK)
              {
                gimp_cage_config_select_add_area (ct->config,
                                                  GIMP_CAGE_MODE_DEFORM, area);
              }
            else
              {
                gimp_cage_config_select_area (ct->config,
                                              GIMP_CAGE_MODE_DEFORM, area);
              }

            ct->tool_state = DEFORM_STATE_WAIT;
          }
          break;
        }
    }

  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}