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); }
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); }
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; } }
/* 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)); }
/* * 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)); }