예제 #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
파일: gimpcagetool.c 프로젝트: STRNG/gimp
static void
gimp_cage_tool_oper_update (GimpTool         *tool,
                            const GimpCoords *coords,
                            GdkModifierType   state,
                            gboolean          proximity,
                            GimpDisplay      *display)
{
  GimpCageTool *ct        = GIMP_CAGE_TOOL (tool);
  GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);

  if (ct->config)
    {
      ct->hovering_handle = gimp_cage_tool_is_on_handle (ct,
                                                         draw_tool,
                                                         display,
                                                         coords->x,
                                                         coords->y,
                                                         GIMP_TOOL_HANDLE_SIZE_CIRCLE);

      ct->hovering_edge = gimp_cage_tool_is_on_edge (ct,
                                                     coords->x,
                                                     coords->y,
                                                     GIMP_TOOL_HANDLE_SIZE_CIRCLE);
    }

  gimp_draw_tool_pause (draw_tool);

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

  gimp_draw_tool_resume (draw_tool);
}
예제 #4
0
static gboolean
gimp_cage_tool_key_press (GimpTool    *tool,
                          GdkEventKey *kevent,
                          GimpDisplay *display)
{
    GimpCageTool *ct = GIMP_CAGE_TOOL (tool);

    switch (kevent->keyval)
    {
    case GDK_KEY_BackSpace:
        if (! ct->cage_complete && ct->tool_state == CAGE_STATE_WAIT)
        {
            gimp_cage_tool_remove_last_handle (ct);
        }
        else if (ct->cage_complete && ct->tool_state == CAGE_STATE_WAIT)
        {
            gimp_cage_config_remove_selected_points(ct->config);

            /* if the cage have less than 3 handles, we reopen it */
            if (gimp_cage_config_get_n_points(ct->config) <= 2)
                ct->cage_complete = FALSE;
        }
        return TRUE;

    case GDK_KEY_Return:
    case GDK_KEY_KP_Enter:
    case GDK_KEY_ISO_Enter:
        if (ct->cage_complete == FALSE && gimp_cage_config_get_n_points (ct->config) > 2)
        {
            g_object_set (gimp_tool_get_options (tool),
                          "cage-mode", GIMP_CAGE_MODE_DEFORM,
                          NULL);
        }
        else if (ct->tool_state == DEFORM_STATE_WAIT)
        {
            gimp_tool_control_push_preserve (tool->control, TRUE);

            gimp_image_map_commit (ct->image_map);
            g_object_unref (ct->image_map);
            ct->image_map = NULL;

            gimp_tool_control_pop_preserve (tool->control);

            gimp_image_flush (gimp_display_get_image (display));

            gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
        }
        break;

    case GDK_KEY_Escape:
        gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
        return TRUE;

    default:
        break;
    }

    return FALSE;
}
예제 #5
0
static void
gimp_cage_tool_control (GimpTool       *tool,
                        GimpToolAction  action,
                        GimpDisplay    *display)
{
  GimpCageTool *ct = GIMP_CAGE_TOOL (tool);

  switch (action)
    {
    case GIMP_TOOL_ACTION_PAUSE:
    case GIMP_TOOL_ACTION_RESUME:
      break;

    case GIMP_TOOL_ACTION_HALT:
      if (ct->config)
        {
          g_object_unref (ct->config);
          ct->config = NULL;
        }

      if (ct->coef)
        {
          g_object_unref (ct->coef);
          ct->coef = NULL;
        }

      if (ct->render_node)
        {
          g_object_unref (ct->render_node);
          ct->render_node = NULL;
          ct->coef_node   = NULL;
          ct->cage_node   = NULL;
        }

      if (ct->image_map)
        {
          gimp_tool_control_push_preserve (tool->control, TRUE);

          gimp_image_map_abort (ct->image_map);
          g_object_unref (ct->image_map);
          ct->image_map = NULL;

          gimp_tool_control_pop_preserve (tool->control);

          gimp_image_flush (gimp_display_get_image (tool->display));
        }

      tool->display = NULL;

      g_object_set (gimp_tool_get_options (tool),
                    "cage-mode", GIMP_CAGE_MODE_CAGE_CHANGE,
                    NULL);
      break;
    }

  GIMP_TOOL_CLASS (parent_class)->control (tool, action, display);
}
예제 #6
0
파일: gimpcagetool.c 프로젝트: STRNG/gimp
static gboolean
gimp_cage_tool_key_press (GimpTool    *tool,
                          GdkEventKey *kevent,
                          GimpDisplay *display)
{
  GimpCageTool *ct = GIMP_CAGE_TOOL (tool);

  switch (kevent->keyval)
    {
    case GDK_KEY_BackSpace:
      if (ct->tool_state == CAGE_STATE_WAIT)
        {
          gimp_cage_tool_remove_last_handle (ct);
        }
      else if (ct->tool_state == DEFORM_STATE_WAIT)
        {
          gimp_cage_config_remove_selected_points(ct->config);

          /* if the cage have less than 3 handles, we reopen it */
          if (gimp_cage_config_get_n_points(ct->config) <= 2)
            {
              ct->tool_state = CAGE_STATE_WAIT;
            }

          gimp_cage_tool_compute_coef (ct);
          gimp_cage_tool_render_node_update (ct);
        }
      return TRUE;

    case GDK_KEY_Return:
    case GDK_KEY_KP_Enter:
    case GDK_KEY_ISO_Enter:
      if (! gimp_cage_tool_is_complete (ct) &&
          gimp_cage_config_get_n_points (ct->config) > 2)
        {
          g_object_set (gimp_tool_get_options (tool),
                        "cage-mode", GIMP_CAGE_MODE_DEFORM,
                        NULL);
        }
      else if (ct->tool_state == DEFORM_STATE_WAIT)
        {
          gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, display);
          gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
        }
      return TRUE;

    case GDK_KEY_Escape:
      gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
      return TRUE;

    default:
      break;
    }

  return FALSE;
}
예제 #7
0
파일: gimpcagetool.c 프로젝트: STRNG/gimp
static void
gimp_cage_tool_control (GimpTool       *tool,
                        GimpToolAction  action,
                        GimpDisplay    *display)
{
  GimpCageTool *ct = GIMP_CAGE_TOOL (tool);

  switch (action)
    {
    case GIMP_TOOL_ACTION_PAUSE:
    case GIMP_TOOL_ACTION_RESUME:
      break;

    case GIMP_TOOL_ACTION_HALT:
      gimp_cage_tool_halt (ct);
      break;

    case GIMP_TOOL_ACTION_COMMIT:
      gimp_cage_tool_commit (ct);
      break;
    }

  GIMP_TOOL_CLASS (parent_class)->control (tool, action, display);
}
예제 #8
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));
    }
}
예제 #9
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));
}
예제 #10
0
파일: gimpcagetool.c 프로젝트: STRNG/gimp
static void
gimp_cage_tool_button_press (GimpTool            *tool,
                             const GimpCoords    *coords,
                             guint32              time,
                             GdkModifierType      state,
                             GimpButtonPressType  press_type,
                             GimpDisplay         *display)
{
  GimpCageTool    *ct        = GIMP_CAGE_TOOL (tool);
  GimpDrawTool    *draw_tool = GIMP_DRAW_TOOL (tool);
  gint             handle    = -1;
  gint             edge      = -1;

  if (display != tool->display)
    gimp_cage_tool_start (ct, display);

  gimp_tool_control_activate (tool->control);

  if (ct->config)
    {
      handle = gimp_cage_tool_is_on_handle (ct,
                                            draw_tool,
                                            display,
                                            coords->x,
                                            coords->y,
                                            GIMP_TOOL_HANDLE_SIZE_CIRCLE);
      edge = gimp_cage_tool_is_on_edge (ct,
                                        coords->x,
                                        coords->y,
                                        GIMP_TOOL_HANDLE_SIZE_CIRCLE);
    }

  ct->movement_start_x = coords->x;
  ct->movement_start_y = coords->y;

  switch (ct->tool_state)
    {
      case CAGE_STATE_INIT:
        /* No handle yet, we add the first one and swith the tool to
         * moving handle state.
         */
        gimp_cage_config_add_cage_point (ct->config,
                                         coords->x - ct->offset_x,
                                         coords->y - ct->offset_y);
        gimp_cage_config_select_point (ct->config, 0);
        ct->tool_state = CAGE_STATE_MOVE_HANDLE;
        break;

      case CAGE_STATE_WAIT:
        if (handle == -1 && edge <= 0)
          {
            /* User clicked on the background, we add a new handle
             * and move it
             */
            gimp_cage_config_add_cage_point (ct->config,
                                             coords->x - ct->offset_x,
                                             coords->y - ct->offset_y);
            gimp_cage_config_select_point (ct->config,
                                           gimp_cage_config_get_n_points (ct->config) - 1);
            ct->tool_state = CAGE_STATE_MOVE_HANDLE;
          }
        else if (handle == 0 && gimp_cage_config_get_n_points (ct->config) > 2)
          {
            /* User clicked on the first handle, we wait for
             * release for closing the cage and switching to
             * deform if possible
             */
            gimp_cage_config_select_point (ct->config, 0);
            ct->tool_state = CAGE_STATE_CLOSING;
          }
        else if (handle >= 0)
          {
            /* User clicked on a handle, so we move it */

            if (state & GDK_SHIFT_MASK)
              {
                /* Multiple selection */

                gimp_cage_config_toggle_point_selection (ct->config, handle);
              }
            else
              {
                /* New selection */

                if (! gimp_cage_config_point_is_selected (ct->config, handle))
                  {
                    gimp_cage_config_select_point (ct->config, handle);
                  }
              }

            ct->tool_state = CAGE_STATE_MOVE_HANDLE;
          }
        else if (edge > 0)
          {
            /* User clicked on an edge, we add a new handle here and select it */

            gimp_cage_config_insert_cage_point (ct->config, edge, coords->x, coords->y);
            gimp_cage_config_select_point (ct->config, edge);
            ct->tool_state = CAGE_STATE_MOVE_HANDLE;
          }
        break;

      case DEFORM_STATE_WAIT:
        if (handle == -1)
          {
            /* User clicked on the background, we start a rubber band
             * selection
             */
            ct->selection_start_x = coords->x;
            ct->selection_start_y = coords->y;
            ct->tool_state = DEFORM_STATE_SELECTING;
          }

        if (handle >= 0)
          {
            /* User clicked on a handle, so we move it */

            if (state & GDK_SHIFT_MASK)
              {
                /* Multiple selection */

                gimp_cage_config_toggle_point_selection (ct->config, handle);
              }
            else
              {
                /* New selection */

                if (! gimp_cage_config_point_is_selected (ct->config, handle))
                  {
                    gimp_cage_config_select_point (ct->config, handle);
                  }
              }

            ct->tool_state = DEFORM_STATE_MOVE_HANDLE;
          }
        break;
    }
}
예제 #11
0
파일: gimpcagetool.c 프로젝트: STRNG/gimp
static void
gimp_cage_tool_options_notify (GimpTool         *tool,
                               GimpToolOptions  *options,
                               const GParamSpec *pspec)
{
  GimpCageTool *ct = GIMP_CAGE_TOOL (tool);

  GIMP_TOOL_CLASS (parent_class)->options_notify (tool, options, pspec);

  if (! tool->display)
    return;

  gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));

  if (strcmp (pspec->name, "cage-mode") == 0)
    {
      GimpCageMode mode;

      g_object_get (options,
                    "cage-mode", &mode,
                    NULL);

      if (mode == GIMP_CAGE_MODE_DEFORM)
        {
          /* switch to deform mode */

          gimp_cage_config_reset_displacement (ct->config);
          gimp_cage_config_reverse_cage_if_needed (ct->config);
          gimp_tool_push_status (tool, tool->display,
                                 _("Press ENTER to commit the transform"));
          ct->tool_state = DEFORM_STATE_WAIT;

          if (! ct->render_node)
            {
              gimp_cage_tool_create_render_node (ct);
            }

          if (ct->dirty_coef)
            {
              gimp_cage_tool_compute_coef (ct);
              gimp_cage_tool_render_node_update (ct);
            }

          if (! ct->image_map)
            {
              GimpImage    *image    = gimp_display_get_image (tool->display);
              GimpDrawable *drawable = gimp_image_get_active_drawable (image);

              gimp_cage_tool_create_image_map (ct, drawable);
            }

          gimp_cage_tool_image_map_update (ct);
        }
      else
        {
          /* switch to edit mode */
          gimp_image_map_abort (ct->image_map);

          gimp_tool_pop_status (tool, tool->display);
          ct->tool_state = CAGE_STATE_WAIT;
        }
    }
  else if (strcmp  (pspec->name, "fill-plain-color") == 0)
    {
      gimp_cage_tool_render_node_update (ct);
      gimp_cage_tool_image_map_update (ct);
    }

  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}