diff options
Diffstat (limited to 'app/display/gimpdisplayshell-cursor.c')
-rw-r--r-- | app/display/gimpdisplayshell-cursor.c | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/app/display/gimpdisplayshell-cursor.c b/app/display/gimpdisplayshell-cursor.c new file mode 100644 index 0000000..5a536d5 --- /dev/null +++ b/app/display/gimpdisplayshell-cursor.c @@ -0,0 +1,295 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <gegl.h> +#include <gtk/gtk.h> + +#include "display-types.h" + +#include "config/gimpguiconfig.h" + +#include "core/gimpimage.h" + +#include "widgets/gimpcursor.h" +#include "widgets/gimpdialogfactory.h" +#include "widgets/gimpdockcontainer.h" +#include "widgets/gimpsessioninfo.h" + +#include "gimpcanvascursor.h" +#include "gimpdisplay.h" +#include "gimpcursorview.h" +#include "gimpdisplayshell.h" +#include "gimpdisplayshell-cursor.h" +#include "gimpdisplayshell-transform.h" +#include "gimpstatusbar.h" + + +static void gimp_display_shell_real_set_cursor (GimpDisplayShell *shell, + GimpCursorType cursor_type, + GimpToolCursorType tool_cursor, + GimpCursorModifier modifier, + gboolean always_install); + + +/* public functions */ + +void +gimp_display_shell_set_cursor (GimpDisplayShell *shell, + GimpCursorType cursor_type, + GimpToolCursorType tool_cursor, + GimpCursorModifier modifier) +{ + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + + if (! shell->using_override_cursor) + { + gimp_display_shell_real_set_cursor (shell, + cursor_type, + tool_cursor, + modifier, + FALSE); + } +} + +void +gimp_display_shell_unset_cursor (GimpDisplayShell *shell) +{ + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + + if (! shell->using_override_cursor) + { + gimp_display_shell_real_set_cursor (shell, + (GimpCursorType) -1, 0, 0, FALSE); + } +} + +void +gimp_display_shell_set_override_cursor (GimpDisplayShell *shell, + GimpCursorType cursor_type) +{ + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + + if (! shell->using_override_cursor || + (shell->using_override_cursor && + shell->override_cursor != cursor_type)) + { + shell->override_cursor = cursor_type; + shell->using_override_cursor = TRUE; + + gimp_cursor_set (shell->canvas, + shell->cursor_handedness, + cursor_type, + GIMP_TOOL_CURSOR_NONE, + GIMP_CURSOR_MODIFIER_NONE); + } +} + +void +gimp_display_shell_unset_override_cursor (GimpDisplayShell *shell) +{ + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + + if (shell->using_override_cursor) + { + shell->using_override_cursor = FALSE; + + gimp_display_shell_real_set_cursor (shell, + shell->current_cursor, + shell->tool_cursor, + shell->cursor_modifier, + TRUE); + } +} + +void +gimp_display_shell_update_software_cursor (GimpDisplayShell *shell, + GimpCursorPrecision precision, + gint display_x, + gint display_y, + gdouble image_x, + gdouble image_y) +{ + GimpImageWindow *image_window; + GimpDialogFactory *factory; + GimpStatusbar *statusbar; + GtkWidget *widget; + GimpImage *image; + + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + + image = gimp_display_get_image (shell->display); + + if (shell->draw_cursor && + shell->proximity && + display_x >= 0 && + display_y >= 0) + { + gimp_canvas_item_begin_change (shell->cursor); + + gimp_canvas_cursor_set (shell->cursor, + display_x, + display_y); + gimp_canvas_item_set_visible (shell->cursor, TRUE); + + gimp_canvas_item_end_change (shell->cursor); + } + else + { + gimp_canvas_item_set_visible (shell->cursor, FALSE); + } + + /* use the passed image_coords for the statusbar because they are + * possibly snapped... + */ + statusbar = gimp_display_shell_get_statusbar (shell); + + gimp_statusbar_update_cursor (statusbar, precision, image_x, image_y); + + image_window = gimp_display_shell_get_window (shell); + factory = gimp_dock_container_get_dialog_factory (GIMP_DOCK_CONTAINER (image_window)); + + widget = gimp_dialog_factory_find_widget (factory, "gimp-cursor-view"); + + if (widget) + { + GtkWidget *cursor_view = gtk_bin_get_child (GTK_BIN (widget)); + + if (cursor_view) + { + gint t_x = -1; + gint t_y = -1; + + /* ...but use the unsnapped display_coords for the info window */ + if (display_x >= 0 && display_y >= 0) + gimp_display_shell_untransform_xy (shell, display_x, display_y, + &t_x, &t_y, FALSE); + + gimp_cursor_view_update_cursor (GIMP_CURSOR_VIEW (cursor_view), + image, shell->unit, + t_x, t_y); + } + } +} + +void +gimp_display_shell_clear_software_cursor (GimpDisplayShell *shell) +{ + GimpImageWindow *image_window; + GimpDialogFactory *factory; + GimpStatusbar *statusbar; + GtkWidget *widget; + + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + + gimp_canvas_item_set_visible (shell->cursor, FALSE); + + statusbar = gimp_display_shell_get_statusbar (shell); + + gimp_statusbar_clear_cursor (statusbar); + + image_window = gimp_display_shell_get_window (shell); + factory = gimp_dock_container_get_dialog_factory (GIMP_DOCK_CONTAINER (image_window)); + + widget = gimp_dialog_factory_find_widget (factory, "gimp-cursor-view"); + + if (widget) + { + GtkWidget *cursor_view = gtk_bin_get_child (GTK_BIN (widget)); + + if (cursor_view) + gimp_cursor_view_clear_cursor (GIMP_CURSOR_VIEW (cursor_view)); + } +} + + +/* private functions */ + +static void +gimp_display_shell_real_set_cursor (GimpDisplayShell *shell, + GimpCursorType cursor_type, + GimpToolCursorType tool_cursor, + GimpCursorModifier modifier, + gboolean always_install) +{ + GimpHandedness cursor_handedness; + + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + + if (cursor_type == (GimpCursorType) -1) + { + shell->current_cursor = cursor_type; + + if (gtk_widget_is_drawable (shell->canvas)) + gdk_window_set_cursor (gtk_widget_get_window (shell->canvas), NULL); + + return; + } + + if (cursor_type != GIMP_CURSOR_NONE && + cursor_type != GIMP_CURSOR_BAD) + { + switch (shell->display->config->cursor_mode) + { + case GIMP_CURSOR_MODE_TOOL_ICON: + break; + + case GIMP_CURSOR_MODE_TOOL_CROSSHAIR: + if (cursor_type < GIMP_CURSOR_CORNER_TOP || + cursor_type > GIMP_CURSOR_SIDE_TOP_LEFT) + { + /* the corner and side cursors count as crosshair, so leave + * them and override everything else + */ + cursor_type = GIMP_CURSOR_CROSSHAIR_SMALL; + } + break; + + case GIMP_CURSOR_MODE_CROSSHAIR: + cursor_type = GIMP_CURSOR_CROSSHAIR; + tool_cursor = GIMP_TOOL_CURSOR_NONE; + + if (modifier != GIMP_CURSOR_MODIFIER_BAD) + { + /* the bad modifier is always shown */ + modifier = GIMP_CURSOR_MODIFIER_NONE; + } + break; + } + } + + cursor_type = gimp_cursor_rotate (cursor_type, shell->rotate_angle); + + cursor_handedness = GIMP_GUI_CONFIG (shell->display->config)->cursor_handedness; + + if (shell->cursor_handedness != cursor_handedness || + shell->current_cursor != cursor_type || + shell->tool_cursor != tool_cursor || + shell->cursor_modifier != modifier || + always_install) + { + shell->cursor_handedness = cursor_handedness; + shell->current_cursor = cursor_type; + shell->tool_cursor = tool_cursor; + shell->cursor_modifier = modifier; + + gimp_cursor_set (shell->canvas, + cursor_handedness, + cursor_type, tool_cursor, modifier); + } +} |