예제 #1
0
static void
gimp_image_map_tool_guide_moved (GimpGuide        *guide,
                                 const GParamSpec *pspec,
                                 GimpImageMapTool *im_tool)
{
  GimpImageMapOptions *options = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (im_tool);
  GimpItem            *item    = GIMP_ITEM (im_tool->drawable);
  gdouble              position;

  if (options->preview_alignment == GIMP_ALIGN_LEFT ||
      options->preview_alignment == GIMP_ALIGN_RIGHT)
    {
      position = ((gdouble) (gimp_guide_get_position (guide) -
                             gimp_item_get_offset_x (item)) /
                  (gdouble) gimp_item_get_width (item));
    }
  else
    {
      position = ((gdouble) (gimp_guide_get_position (guide) -
                             gimp_item_get_offset_y (item)) /
                  (gdouble) gimp_item_get_height (item));
    }

  g_object_set (options,
                "preview-position", CLAMP (position, 0.0, 1.0),
                NULL);
}
예제 #2
0
static void
gimp_image_map_tool_create_map (GimpImageMapTool *tool)
{
  GimpImageMapOptions *options   = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (tool);
  GimpToolInfo        *tool_info = GIMP_TOOL (tool)->tool_info;

  if (tool->image_map)
    {
      gimp_image_map_abort (tool->image_map);
      g_object_unref (tool->image_map);
    }

  g_assert (tool->operation);

  tool->image_map = gimp_image_map_new (tool->drawable,
                                        tool->undo_desc,
                                        tool->operation,
                                        gimp_viewable_get_icon_name (GIMP_VIEWABLE (tool_info)));

  gimp_image_map_set_region (tool->image_map, options->region);

  g_signal_connect (tool->image_map, "flush",
                    G_CALLBACK (gimp_image_map_tool_flush),
                    tool);
}
예제 #3
0
static void
gimp_image_map_tool_add_guide (GimpImageMapTool *im_tool)
{
  GimpImageMapOptions *options = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (im_tool);
  GimpItem            *item;
  GimpImage           *image;
  GimpOrientationType  orientation;
  gint                 position;

  if (im_tool->percent_guide)
    return;

  item = GIMP_ITEM (im_tool->drawable);
  image = gimp_item_get_image (item);

  if (options->preview_alignment == GIMP_ALIGN_LEFT ||
      options->preview_alignment == GIMP_ALIGN_RIGHT)
    {
      orientation = GIMP_ORIENTATION_VERTICAL;

      position = (gimp_item_get_offset_x (item) +
                  gimp_item_get_width (item) *
                  options->preview_position);
    }
  else
    {
      orientation = GIMP_ORIENTATION_HORIZONTAL;

      position = (gimp_item_get_offset_y (item) +
                  gimp_item_get_height (item) *
                  options->preview_position);
    }

  im_tool->percent_guide = gimp_guide_custom_new (orientation,
                                                  image->gimp->next_guide_ID++,
                                                  GIMP_GUIDE_STYLE_SPLIT_VIEW);

  gimp_image_add_guide (image, im_tool->percent_guide, position);

  g_signal_connect (im_tool->percent_guide, "removed",
                    G_CALLBACK (gimp_image_map_tool_guide_removed),
                    im_tool);
  g_signal_connect (im_tool->percent_guide, "notify::position",
                    G_CALLBACK (gimp_image_map_tool_guide_moved),
                    im_tool);
}
예제 #4
0
void
gimp_image_map_tool_preview (GimpImageMapTool *image_map_tool)
{
  GimpTool            *tool;
  GimpImageMapOptions *options;

  g_return_if_fail (GIMP_IS_IMAGE_MAP_TOOL (image_map_tool));

  tool    = GIMP_TOOL (image_map_tool);
  options = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (tool);

  if (image_map_tool->image_map && options->preview)
    {
      gimp_tool_control_set_preserve (tool->control, TRUE);

      gimp_image_map_tool_map (image_map_tool);

      gimp_tool_control_set_preserve (tool->control, FALSE);
    }
}
예제 #5
0
static void
gimp_image_map_tool_guide_removed (GimpGuide        *guide,
                                   GimpImageMapTool *im_tool)
{
  GimpImageMapOptions *options = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (im_tool);

  g_signal_handlers_disconnect_by_func (G_OBJECT (im_tool->percent_guide),
                                        gimp_image_map_tool_guide_removed,
                                        im_tool);
  g_signal_handlers_disconnect_by_func (G_OBJECT (im_tool->percent_guide),
                                        gimp_image_map_tool_guide_moved,
                                        im_tool);

  g_object_unref (im_tool->percent_guide);
  im_tool->percent_guide = NULL;

  g_object_set (options,
                "preview-split", FALSE,
                NULL);
}
예제 #6
0
static void
gimp_image_map_tool_commit (GimpImageMapTool *im_tool)
{
  GimpTool *tool = GIMP_TOOL (im_tool);

  if (im_tool->gui)
    gimp_tool_gui_hide (im_tool->gui);

  if (im_tool->image_map)
    {
      GimpImageMapOptions *options = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (tool);

      gimp_tool_control_push_preserve (tool->control, TRUE);

      if (! options->preview)
        gimp_image_map_apply (im_tool->image_map, NULL);

      gimp_image_map_commit (im_tool->image_map, GIMP_PROGRESS (tool), TRUE);
      g_object_unref (im_tool->image_map);
      im_tool->image_map = NULL;

      gimp_tool_control_pop_preserve (tool->control);

      gimp_image_map_tool_remove_guide (im_tool);

      gimp_image_flush (gimp_display_get_image (tool->display));

      if (im_tool->config && im_tool->settings_box)
        {
          GimpGuiConfig *config = GIMP_GUI_CONFIG (tool->tool_info->gimp->config);

          gimp_settings_box_add_current (GIMP_SETTINGS_BOX (im_tool->settings_box),
                                         config->image_map_tool_max_recent);
        }
    }

  tool->display  = NULL;
  tool->drawable = NULL;
}
예제 #7
0
static void
gimp_image_map_tool_move_guide (GimpImageMapTool *im_tool)
{
  GimpImageMapOptions *options = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (im_tool);
  GimpItem            *item;
  GimpOrientationType  orientation;
  gint                 position;

  if (! im_tool->percent_guide)
    return;

  item = GIMP_ITEM (im_tool->drawable);

  if (options->preview_alignment == GIMP_ALIGN_LEFT ||
      options->preview_alignment == GIMP_ALIGN_RIGHT)
    {
      orientation = GIMP_ORIENTATION_VERTICAL;

      position = (gimp_item_get_offset_x (item) +
                  gimp_item_get_width (item) *
                  options->preview_position);
    }
  else
    {
      orientation = GIMP_ORIENTATION_HORIZONTAL;

      position = (gimp_item_get_offset_y (item) +
                  gimp_item_get_height (item) *
                  options->preview_position);
    }

  if (orientation != gimp_guide_get_orientation (im_tool->percent_guide) ||
      position    != gimp_guide_get_position (im_tool->percent_guide))
    {
      gimp_guide_set_orientation (im_tool->percent_guide, orientation);
      gimp_image_move_guide (gimp_item_get_image (item),
                             im_tool->percent_guide, position, FALSE);
    }
}
예제 #8
0
static void
gimp_image_map_tool_create_map (GimpImageMapTool *im_tool)
{
  GimpImageMapOptions *options = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (im_tool);

  if (im_tool->image_map)
    {
      gimp_image_map_abort (im_tool->image_map);
      g_object_unref (im_tool->image_map);
    }

  g_assert (im_tool->operation);

  im_tool->image_map = gimp_image_map_new (im_tool->drawable,
                                           im_tool->undo_desc,
                                           im_tool->operation,
                                           im_tool->icon_name);

  gimp_image_map_set_region (im_tool->image_map, options->region);

  g_signal_connect (im_tool->image_map, "flush",
                    G_CALLBACK (gimp_image_map_tool_flush),
                    im_tool);
}
예제 #9
0
static void
gimp_image_map_tool_response (GtkWidget        *widget,
                              gint              response_id,
                              GimpImageMapTool *image_map_tool)
{
  GimpTool *tool = GIMP_TOOL (image_map_tool);

  switch (response_id)
    {
    case RESPONSE_RESET:
      gimp_image_map_tool_reset (image_map_tool);
      gimp_image_map_tool_preview (image_map_tool);
      break;

    case GTK_RESPONSE_OK:
      gimp_dialog_factory_hide_dialog (image_map_tool->shell);

      if (image_map_tool->image_map)
        {
          GimpImageMapOptions *options = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (tool);

          gimp_tool_control_set_preserve (tool->control, TRUE);

          if (! options->preview)
            gimp_image_map_tool_map (image_map_tool);

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

          gimp_tool_control_set_preserve (tool->control, FALSE);

          gimp_image_flush (tool->display->image);

          if (image_map_tool->config)
            gimp_settings_box_add_current (GIMP_SETTINGS_BOX (image_map_tool->settings_box));
        }

      tool->display  = NULL;
      tool->drawable = NULL;
      break;

    default:
      gimp_dialog_factory_hide_dialog (image_map_tool->shell);

      if (image_map_tool->image_map)
        {
          gimp_tool_control_set_preserve (tool->control, TRUE);

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

          gimp_tool_control_set_preserve (tool->control, FALSE);

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

      tool->display  = NULL;
      tool->drawable = NULL;
      break;
    }
}
예제 #10
0
static void
gimp_operation_tool_color_picked (GimpImageMapTool  *im_tool,
                                  gpointer           identifier,
                                  gdouble            x,
                                  gdouble            y,
                                  const Babl        *sample_format,
                                  const GimpRGB     *color)
{
    GimpOperationTool  *tool = GIMP_OPERATION_TOOL (im_tool);
    gchar             **pspecs;

    pspecs = g_strsplit (identifier, ":", 2);

    if (pspecs[1])
    {
        GimpImageMapOptions *options      = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (tool);
        GimpDrawable        *drawable     = GIMP_TOOL (im_tool)->drawable;
        GObjectClass        *object_class = G_OBJECT_GET_CLASS (im_tool->config);
        GParamSpec          *pspec_x;
        GParamSpec          *pspec_y;
        gint                 width        = 1;
        gint                 height       = 1;

        if (drawable)
        {
            gint off_x, off_y;

            gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);

            x -= off_x;
            y -= off_y;

            switch (options->region)
            {
            case GIMP_IMAGE_MAP_REGION_SELECTION:
                if (gimp_item_mask_intersect (GIMP_ITEM (drawable),
                                              &off_x, &off_y, &width, &height))
                {
                    x -= off_x;
                    y -= off_y;
                }
                break;

            case GIMP_IMAGE_MAP_REGION_DRAWABLE:
                width  = gimp_item_get_width  (GIMP_ITEM (drawable));
                height = gimp_item_get_height (GIMP_ITEM (drawable));
                break;
            }
        }

        pspec_x = g_object_class_find_property (object_class, pspecs[0]);
        pspec_y = g_object_class_find_property (object_class, pspecs[1]);

        if (pspec_x && pspec_y &&
                G_PARAM_SPEC_TYPE (pspec_x) == G_PARAM_SPEC_TYPE (pspec_y))
        {
            GValue value_x = G_VALUE_INIT;
            GValue value_y = G_VALUE_INIT;

            g_value_init (&value_x, G_PARAM_SPEC_VALUE_TYPE (pspec_x));
            g_value_init (&value_y, G_PARAM_SPEC_VALUE_TYPE (pspec_y));

#define HAS_KEY(p,k,v) gimp_gegl_param_spec_has_key (p, k, v)

            if (HAS_KEY (pspec_x, "unit", "relative-coordinate") &&
                    HAS_KEY (pspec_y, "unit", "relative-coordinate"))
            {
                x /= (gdouble) width;
                y /= (gdouble) height;
            }

            if (G_IS_PARAM_SPEC_INT (pspec_x))
            {
                g_value_set_int (&value_x, x);
                g_value_set_int (&value_y, y);

                g_param_value_validate (pspec_x, &value_x);
                g_param_value_validate (pspec_y, &value_y);

                g_object_set (im_tool->config,
                              pspecs[0], g_value_get_int (&value_x),
                              pspecs[1], g_value_get_int (&value_y),
                              NULL);
            }
            else if (G_IS_PARAM_SPEC_DOUBLE (pspec_x))
            {
                g_value_set_double (&value_x, x);
                g_value_set_double (&value_y, y);

                g_param_value_validate (pspec_x, &value_x);
                g_param_value_validate (pspec_y, &value_y);

                g_object_set (im_tool->config,
                              pspecs[0], g_value_get_double (&value_x),
                              pspecs[1], g_value_get_double (&value_y),
                              NULL);
            }
            else
            {
                g_warning ("%s: unhandled param spec of type %s",
                           G_STRFUNC, G_PARAM_SPEC_TYPE_NAME (pspec_x));
            }

            g_value_unset (&value_x);
            g_value_unset (&value_y);
        }
    }
    else
    {
        g_object_set (im_tool->config,
                      pspecs[0], color,
                      NULL);
    }

    g_strfreev (pspecs);
}
예제 #11
0
static void
gimp_image_map_tool_button_press (GimpTool            *tool,
                                  const GimpCoords    *coords,
                                  guint32              time,
                                  GdkModifierType      state,
                                  GimpButtonPressType  press_type,
                                  GimpDisplay         *display)
{
  GimpImageMapTool *im_tool = GIMP_IMAGE_MAP_TOOL (tool);

  if (! gimp_image_map_tool_on_guide (im_tool, coords, display))
    {
      GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time, state,
                                                    press_type, display);
    }
  else
    {
      GimpImageMapOptions *options = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (tool);

      if (state & gimp_get_extend_selection_mask ())
        {
          GimpAlignmentType alignment;

          /* switch side */
          switch (options->preview_alignment)
            {
            case GIMP_ALIGN_LEFT:   alignment = GIMP_ALIGN_RIGHT;  break;
            case GIMP_ALIGN_RIGHT:  alignment = GIMP_ALIGN_LEFT;   break;
            case GIMP_ALIGN_TOP:    alignment = GIMP_ALIGN_BOTTOM; break;
            case GIMP_ALIGN_BOTTOM: alignment = GIMP_ALIGN_TOP;    break;
            default:
              g_return_if_reached ();
            }

          g_object_set (options, "preview-alignment", alignment, NULL);
        }
      else if (state & gimp_get_toggle_behavior_mask ())
        {
          GimpItem          *item = GIMP_ITEM (im_tool->drawable);
          GimpAlignmentType  alignment;
          gdouble            position;

          /* switch orientation */
          switch (options->preview_alignment)
            {
            case GIMP_ALIGN_LEFT:   alignment = GIMP_ALIGN_TOP;    break;
            case GIMP_ALIGN_RIGHT:  alignment = GIMP_ALIGN_BOTTOM; break;
            case GIMP_ALIGN_TOP:    alignment = GIMP_ALIGN_LEFT;   break;
            case GIMP_ALIGN_BOTTOM: alignment = GIMP_ALIGN_RIGHT;  break;
            default:
              g_return_if_reached ();
            }

          if (alignment == GIMP_ALIGN_LEFT ||
              alignment == GIMP_ALIGN_RIGHT)
            {
              position = ((coords->x - gimp_item_get_offset_x (item)) /
                          gimp_item_get_width (item));
            }
          else
            {
              position = ((coords->y - gimp_item_get_offset_y (item)) /
                          gimp_item_get_height (item));
            }

          g_object_set (options,
                        "preview-alignment", alignment,
                        "preview-position",  CLAMP (position, 0.0, 1.0),
                        NULL);
        }
      else
        {
          gimp_guide_tool_start_edit (tool, display,
                                      im_tool->percent_guide);
        }
    }
}
예제 #12
0
void
gimp_image_map_tool_get_operation (GimpImageMapTool *im_tool)
{
  GimpImageMapToolClass *klass;
  GimpToolInfo          *tool_info;
  gchar                 *operation_name;

  g_return_if_fail (GIMP_IS_IMAGE_MAP_TOOL (im_tool));

  klass = GIMP_IMAGE_MAP_TOOL_GET_CLASS (im_tool);

  tool_info = GIMP_TOOL (im_tool)->tool_info;

  if (im_tool->image_map)
    {
      gimp_image_map_abort (im_tool->image_map);
      g_object_unref (im_tool->image_map);
      im_tool->image_map = NULL;
    }

  if (im_tool->operation)
    {
      g_object_unref (im_tool->operation);
      im_tool->operation = NULL;
    }

  if (im_tool->config)
    {
      g_signal_handlers_disconnect_by_func (im_tool->config,
                                            gimp_image_map_tool_config_notify,
                                            im_tool);

      g_object_unref (im_tool->config);
      im_tool->config = NULL;
    }

  if (im_tool->default_config)
    {
      g_object_unref (im_tool->default_config);
      im_tool->default_config = NULL;
    }

  if (im_tool->title)
    {
      g_free (im_tool->title);
      im_tool->title = NULL;
    }

  if (im_tool->description)
    {
      g_free (im_tool->description);
      im_tool->description = NULL;
    }

  if (im_tool->undo_desc)
    {
      g_free (im_tool->undo_desc);
      im_tool->undo_desc = NULL;
    }

  if (im_tool->icon_name)
    {
      g_free (im_tool->icon_name);
      im_tool->icon_name = NULL;
    }

  if (im_tool->help_id)
    {
      g_free (im_tool->help_id);
      im_tool->help_id = NULL;
    }

  operation_name = klass->get_operation (im_tool,
                                         &im_tool->title,
                                         &im_tool->description,
                                         &im_tool->undo_desc,
                                         &im_tool->icon_name,
                                         &im_tool->help_id);

  if (! operation_name)
    operation_name = g_strdup ("gegl:nop");

  if (! im_tool->title)
    im_tool->title = g_strdup (tool_info->blurb);

  if (! im_tool->description)
    im_tool->description = g_strdup (im_tool->title);

  if (! im_tool->undo_desc)
    im_tool->undo_desc = g_strdup (tool_info->blurb);

  if (! im_tool->icon_name)
    im_tool->icon_name =
      g_strdup (gimp_viewable_get_icon_name (GIMP_VIEWABLE (tool_info)));

  if (! im_tool->help_id)
    im_tool->help_id = g_strdup (tool_info->help_id);

  im_tool->operation = gegl_node_new_child (NULL,
                                            "operation", operation_name,
                                            NULL);
  im_tool->config = G_OBJECT (gimp_gegl_config_new (operation_name,
                                                    im_tool->icon_name,
                                                    GIMP_TYPE_SETTINGS));

  gimp_gegl_config_sync_node (GIMP_OBJECT (im_tool->config),
                              im_tool->operation);
  gimp_gegl_config_connect_node (GIMP_OBJECT (im_tool->config),
                                 im_tool->operation);

  if (im_tool->gui)
    {
      gimp_tool_gui_set_title       (im_tool->gui, im_tool->title);
      gimp_tool_gui_set_description (im_tool->gui, im_tool->description);
      gimp_tool_gui_set_icon_name   (im_tool->gui, im_tool->icon_name);
      gimp_tool_gui_set_help_id     (im_tool->gui, im_tool->help_id);
    }

  if (gegl_operation_get_key (operation_name, "position-dependent"))
    {
      if (im_tool->gui)
        gtk_widget_show (im_tool->region_combo);
    }
  else
    {
      if (im_tool->gui)
        gtk_widget_hide (im_tool->region_combo);

      g_object_set (GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (im_tool),
                    "region", GIMP_IMAGE_MAP_REGION_SELECTION,
                    NULL);
    }

  g_free (operation_name);

  g_object_set (GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (im_tool),
                "preview-split",    FALSE,
                "preview-position", 0.5,
                NULL);

  if (im_tool->config)
    g_signal_connect_object (im_tool->config, "notify",
                             G_CALLBACK (gimp_image_map_tool_config_notify),
                             G_OBJECT (im_tool), 0);

  if (GIMP_TOOL (im_tool)->drawable)
    gimp_image_map_tool_create_map (im_tool);
}
예제 #13
0
void
gimp_image_map_tool_get_operation (GimpImageMapTool *image_map_tool)
{
  GimpImageMapToolClass *klass;
  gchar                 *operation_name;

  g_return_if_fail (GIMP_IS_IMAGE_MAP_TOOL (image_map_tool));

  klass = GIMP_IMAGE_MAP_TOOL_GET_CLASS (image_map_tool);

  if (image_map_tool->image_map)
    {
      gimp_image_map_abort (image_map_tool->image_map);
      g_object_unref (image_map_tool->image_map);
      image_map_tool->image_map = NULL;
    }

  if (image_map_tool->operation)
    {
      g_object_unref (image_map_tool->operation);
      image_map_tool->operation = NULL;
    }

  if (image_map_tool->config)
    {
      g_signal_handlers_disconnect_by_func (image_map_tool->config,
                                            gimp_image_map_tool_config_notify,
                                            image_map_tool);

      g_object_unref (image_map_tool->config);
      image_map_tool->config = NULL;
    }

  if (image_map_tool->undo_desc)
    {
      g_free (image_map_tool->undo_desc);
      image_map_tool->undo_desc = NULL;
    }

  image_map_tool->operation = klass->get_operation (image_map_tool,
                                                    &image_map_tool->config,
                                                    &image_map_tool->undo_desc);

  if (! image_map_tool->undo_desc)
    image_map_tool->undo_desc =
      g_strdup (GIMP_TOOL (image_map_tool)->tool_info->blurb);

  gegl_node_get (image_map_tool->operation,
                 "operation", &operation_name,
                 NULL);

  if (operation_name &&
      gegl_operation_get_key (operation_name, "position-dependent"))
    {
      if (image_map_tool->region_combo)
        gtk_widget_show (image_map_tool->region_combo);
    }
  else
    {
      if (image_map_tool->region_combo)
        gtk_widget_show (image_map_tool->region_combo);

      g_object_set (GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (image_map_tool),
                    "region", GIMP_IMAGE_MAP_REGION_SELECTION,
                    NULL);
    }

  g_free (operation_name);

  if (image_map_tool->config)
    g_signal_connect_object (image_map_tool->config, "notify",
                             G_CALLBACK (gimp_image_map_tool_config_notify),
                             G_OBJECT (image_map_tool), 0);

  if (GIMP_TOOL (image_map_tool)->drawable)
    gimp_image_map_tool_create_map (image_map_tool);
}