Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  gimpnavigationeditor.c   Sprache: C

 

/* GIMP - The GNU Image Manipulation Program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * gimpnavigationeditor.c
 * Copyright (C) 2001 Michael Natterer <mitch@gimp.org>
 *
 * partly based on app/nav_window
 * Copyright (C) 1999 Andy Thomas <alt@gimp.org>
 *
 * 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 "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"

#include "display-types.h"

#include "config/gimpdisplayconfig.h"

#include "core/gimp.h"
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
#include "core/gimpimageproxy.h"

#include "widgets/gimpdocked.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpmenufactory.h"
#include "widgets/gimpnavigationview.h"
#include "widgets/gimpuimanager.h"
#include "widgets/gimpviewrenderer.h"

#include "gimpdisplay.h"
#include "gimpdisplayshell.h"
#include "gimpdisplayshell-appearance.h"
#include "gimpdisplayshell-scale.h"
#include "gimpdisplayshell-scroll.h"
#include "gimpdisplayshell-transform.h"
#include "gimpnavigationeditor.h"

#include "gimp-intl.h"


static void        gimp_navigation_editor_docked_iface_init            (GimpDockedInterface  *iface);

static void        gimp_navigation_editor_dispose                      (GObject              *object);

static void        gimp_navigation_editor_set_context                  (GimpDocked           *docked,
                                                                        GimpContext          *context);

static GtkWidget * gimp_navigation_editor_new_private                  (GimpMenuFactory      *menu_factory,
                                                                        GimpDisplayShell     *shell);

static void        gimp_navigation_editor_set_shell                    (GimpNavigationEditor *editor,
                                                                        GimpDisplayShell     *shell);
static gboolean    gimp_navigation_editor_button_release               (GtkWidget            *widget,
                                                                        GdkEventButton       *bevent,
                                                                        GimpDisplayShell     *shell);
static void        gimp_navigation_editor_marker_changed               (GimpNavigationView   *view,
                                                                        gdouble               center_x,
                                                                        gdouble               center_y,
                                                                        gdouble               width,
                                                                        gdouble               height,
                                                                        GimpNavigationEditor *editor);
static void        gimp_navigation_editor_zoom                         (GimpNavigationView   *view,
                                                                        GimpZoomType          direction,
                                                                        gdouble               delta,
                                                                        GimpNavigationEditor *editor);
static void        gimp_navigation_editor_scroll                       (GimpNavigationView   *view,
                                                                        GdkEventScroll       *sevent,
                                                                        GimpNavigationEditor *editor);

static void        gimp_navigation_editor_zoom_adj_changed             (GtkAdjustment        *adj,
                                                                        GimpNavigationEditor *editor);

static void        gimp_navigation_editor_shell_infinite_canvas_notify (GimpDisplayShell     *shell,
                                                                        const GParamSpec     *pspec,
                                                                        GimpNavigationEditor *editor);
static void        gimp_navigation_editor_shell_scaled                 (GimpDisplayShell     *shell,
                                                                        GimpNavigationEditor *editor);
static void        gimp_navigation_editor_shell_scrolled               (GimpDisplayShell     *shell,
                                                                        GimpNavigationEditor *editor);
static void        gimp_navigation_editor_shell_rotated                (GimpDisplayShell     *shell,
                                                                        GimpNavigationEditor *editor);
static void        gimp_navigation_editor_shell_reconnect              (GimpDisplayShell     *shell,
                                                                        GimpNavigationEditor *editor);

static void        gimp_navigation_editor_viewable_size_changed        (GimpViewable         *viewable,
                                                                        GimpNavigationEditor *editor);

static void        gimp_navigation_editor_options_show_canvas_notify   (GimpDisplayOptions   *options,
                                                                        const GParamSpec     *pspec,
                                                                        GimpNavigationEditor *editor);

static void        gimp_navigation_editor_update_marker                (GimpNavigationEditor *editor);


G_DEFINE_TYPE_WITH_CODE (GimpNavigationEditor, gimp_navigation_editor,
                         GIMP_TYPE_EDITOR,
                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_DOCKED,
                                                gimp_navigation_editor_docked_iface_init))

#define parent_class gimp_navigation_editor_parent_class


static void
gimp_navigation_editor_class_init (GimpNavigationEditorClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->dispose = gimp_navigation_editor_dispose;
}

static void
gimp_navigation_editor_docked_iface_init (GimpDockedInterface *iface)
{
  iface->set_context = gimp_navigation_editor_set_context;
}

static void
gimp_navigation_editor_init (GimpNavigationEditor *editor)
{
  GtkWidget *frame;

  editor->context       = NULL;
  editor->shell         = NULL;
  editor->scale_timeout = 0;

  frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  gtk_box_pack_start (GTK_BOX (editor), frame, TRUE, TRUE, 0);
  gtk_widget_show (frame);

  editor->view = gimp_view_new_by_types (NULL,
                                         GIMP_TYPE_NAVIGATION_VIEW,
                                         GIMP_TYPE_IMAGE_PROXY,
                                         GIMP_VIEW_SIZE_MEDIUM, 0, TRUE);
  gtk_container_add (GTK_CONTAINER (frame), editor->view);
  gtk_widget_show (editor->view);

  g_signal_connect (editor->view, "marker-changed",
                    G_CALLBACK (gimp_navigation_editor_marker_changed),
                    editor);
  g_signal_connect (editor->view, "zoom",
                    G_CALLBACK (gimp_navigation_editor_zoom),
                    editor);
  g_signal_connect (editor->view, "scroll",
                    G_CALLBACK (gimp_navigation_editor_scroll),
                    editor);

  gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE);
}

static void
gimp_navigation_editor_dispose (GObject *object)
{
  GimpNavigationEditor *editor = GIMP_NAVIGATION_EDITOR (object);

  if (editor->shell)
    gimp_navigation_editor_set_shell (editor, NULL);

  if (editor->scale_timeout)
    {
      g_source_remove (editor->scale_timeout);
      editor->scale_timeout = 0;
    }

  G_OBJECT_CLASS (parent_class)->dispose (object);
}

static void
gimp_navigation_editor_display_changed (GimpContext          *context,
                                        GimpDisplay          *display,
                                        GimpNavigationEditor *editor)
{
  GimpDisplayShell *shell = NULL;

  if (display && gimp_display_get_image (display))
    shell = gimp_display_get_shell (display);

  gimp_navigation_editor_set_shell (editor, shell);
}

static void
gimp_navigation_editor_image_chaged (GimpContext          *context,
                                     GimpImage            *image,
                                     GimpNavigationEditor *editor)
{
  GimpDisplay      *display = gimp_context_get_display (context);
  GimpDisplayShell *shell   = NULL;

  if (display && image)
    shell = gimp_display_get_shell (display);

  gimp_navigation_editor_set_shell (editor, shell);
}

static void
gimp_navigation_editor_set_context (GimpDocked  *docked,
                                    GimpContext *context)
{
  GimpNavigationEditor *editor  = GIMP_NAVIGATION_EDITOR (docked);
  GimpDisplay          *display = NULL;

  if (editor->context)
    {
      g_signal_handlers_disconnect_by_func (editor->context,
                                            gimp_navigation_editor_display_changed,
                                            editor);
      g_signal_handlers_disconnect_by_func (editor->context,
                                            gimp_navigation_editor_image_chaged,
                                            editor);
    }

  editor->context = context;

  if (editor->context)
    {
      g_signal_connect (context, "display-changed",
                        G_CALLBACK (gimp_navigation_editor_display_changed),
                        editor);
      /* make sure to also call gimp_navigation_editor_set_shell() when the
       * last image is closed, even though the display isn't changed, so that
       * the editor is properly cleared.
       */

      g_signal_connect (context, "image-changed",
                        G_CALLBACK (gimp_navigation_editor_image_chaged),
                        editor);

      display = gimp_context_get_display (context);
    }

  gimp_view_renderer_set_context (GIMP_VIEW (editor->view)->renderer,
                                  context);

  gimp_navigation_editor_display_changed (editor->context,
                                          display,
                                          editor);
}


/*  public functions  */

GtkWidget *
gimp_navigation_editor_new (GimpMenuFactory *menu_factory)
{
  return gimp_navigation_editor_new_private (menu_factory, NULL);
}

void
gimp_navigation_editor_popup (GimpDisplayShell *shell,
                              GtkWidget        *widget,
                              GdkEvent         *event,
                              gint              click_x,
                              gint              click_y)
{
  GtkStyleContext      *style = gtk_widget_get_style_context (widget);
  GimpNavigationEditor *editor;
  GimpNavigationView   *view;
  gint                  x, y;
  gint                  view_marker_center_x, view_marker_center_y;
  gint                  view_marker_width, view_marker_height;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
  g_return_if_fail (GTK_IS_WIDGET (widget));

  if (! shell->nav_popup)
    {
      GtkWidget *frame;

      shell->nav_popup = gtk_window_new (GTK_WINDOW_POPUP);

      frame = gtk_frame_new (NULL);
      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
      gtk_container_add (GTK_CONTAINER (shell->nav_popup), frame);
      gtk_widget_show (frame);

      editor =
        GIMP_NAVIGATION_EDITOR (gimp_navigation_editor_new_private (NULL,
                                                                    shell));
      gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (editor));
      gtk_widget_show (GTK_WIDGET (editor));

      g_signal_connect (editor->view, "button-release-event",
                        G_CALLBACK (gimp_navigation_editor_button_release),
                        shell);
    }
  else
    {
      GtkWidget *bin = gtk_bin_get_child (GTK_BIN (shell->nav_popup));

      editor = GIMP_NAVIGATION_EDITOR (gtk_bin_get_child (GTK_BIN (bin)));
    }

  view = GIMP_NAVIGATION_VIEW (editor->view);

  /* Set poup screen */
  gtk_window_set_screen (GTK_WINDOW (shell->nav_popup),
                         gtk_widget_get_screen (widget));
  gtk_window_set_transient_for (GTK_WINDOW (shell->nav_popup),
                                GTK_WINDOW (gtk_widget_get_toplevel (widget)));

  gimp_navigation_view_get_local_marker (view,
                                         &view_marker_center_x,
                                         &view_marker_center_y,
                                         &view_marker_width,
                                         &view_marker_height);
  /* Position the popup */
  {
    GdkMonitor   *monitor;
    GdkRectangle  workarea;
    GtkBorder     border;
    gint          x_origin, y_origin;
    gint          popup_width, popup_height;
    gint          border_width, border_height;
    gint          screen_click_x, screen_click_y;

    monitor = gimp_widget_get_monitor (widget);
    gdk_monitor_get_workarea (monitor, &workarea);

    gdk_window_get_origin (gtk_widget_get_window (widget),
                           &x_origin, &y_origin);

    gtk_style_context_get_border (style, gtk_widget_get_state_flags (widget),
                                  &border);

    screen_click_x = x_origin + click_x;
    screen_click_y = y_origin + click_y;
    border_width   = 2 * border.left;
    border_height  = 2 * border.top;
    popup_width    = GIMP_VIEW (view)->renderer->width  - 2 * border_width;
    popup_height   = GIMP_VIEW (view)->renderer->height - 2 * border_height;

    x = screen_click_x -
        border_width -
        view_marker_center_x;

    y = screen_click_y -
        border_height -
        view_marker_center_y;

    /* When the image is zoomed out and overscrolled, the above
     * calculation risks positioning the popup far far away from the
     * click coordinate. We don't want that, so perform some clamping.
     */

    x = CLAMP (x, screen_click_x - popup_width,  screen_click_x);
    y = CLAMP (y, screen_click_y - popup_height, screen_click_y);

    /* If the popup doesn't fit into the screen, we have a problem.
     * We move the popup onscreen and risk that the pointer is not
     * in the square representing the viewable area anymore. Moving
     * the pointer will make the image scroll by a large amount,
     * but then it works as usual. Probably better than a popup that
     * is completely unusable in the lower right of the screen.
     *
     * Warping the pointer would be another solution ...
     */

    x = CLAMP (x, workarea.x, workarea.x + workarea.width  - popup_width);
    y = CLAMP (y, workarea.y, workarea.y + workarea.height - popup_height);

    gtk_window_move (GTK_WINDOW (shell->nav_popup), x, y);
  }

  gtk_widget_show (shell->nav_popup);
  gdk_display_flush (gtk_widget_get_display (shell->nav_popup));

  /* fill in then grab pointer */
  gimp_navigation_view_set_motion_offset (view, 0, 0);
  gimp_navigation_view_grab_pointer (view, event);
}


/*  private functions  */

static GtkWidget *
gimp_navigation_editor_new_private (GimpMenuFactory  *menu_factory,
                                    GimpDisplayShell *shell)
{
  GimpNavigationEditor *editor;

  g_return_val_if_fail (menu_factory == NULL ||
                        GIMP_IS_MENU_FACTORY (menu_factory), NULL);
  g_return_val_if_fail (shell == NULL || GIMP_IS_DISPLAY_SHELL (shell), NULL);
  g_return_val_if_fail (menu_factory || shell, NULL);

  if (shell)
    {
      Gimp              *gimp   = shell->display->gimp;
      GimpDisplayConfig *config = shell->display->config;
      GimpView          *view;

      editor = g_object_new (GIMP_TYPE_NAVIGATION_EDITOR, NULL);

      view = GIMP_VIEW (editor->view);

      gimp_view_renderer_set_size (view->renderer,
                                   config->nav_preview_size * 3,
                                   view->renderer->border_width);
      gimp_view_renderer_set_context (view->renderer,
                                      gimp_get_user_context (gimp));
      gimp_view_renderer_set_color_config (view->renderer,
                                           gimp_display_shell_get_color_config (shell));

      gimp_navigation_editor_set_shell (editor, shell);

    }
  else
    {
      GtkWidget *hscale;
      GtkWidget *hbox;

      editor = g_object_new (GIMP_TYPE_NAVIGATION_EDITOR,
                             "menu-factory",    menu_factory,
                             "menu-identifier", "<NavigationEditor>",
                             NULL);

      gtk_widget_set_size_request (editor->view,
                                   GIMP_VIEW_SIZE_HUGE,
                                   GIMP_VIEW_SIZE_HUGE);
      gimp_view_set_expand (GIMP_VIEW (editor->view), TRUE);

      /* the editor buttons */

      editor->zoom_out_button =
        gimp_editor_add_action_button (GIMP_EDITOR (editor), "view",
                                       "view-zoom-out", NULL);

      editor->zoom_in_button =
        gimp_editor_add_action_button (GIMP_EDITOR (editor), "view",
                                       "view-zoom-in", NULL);

      editor->zoom_100_button =
        gimp_editor_add_action_button (GIMP_EDITOR (editor), "view",
                                       "view-zoom-1-1", NULL);

      editor->zoom_fit_in_button =
        gimp_editor_add_action_button (GIMP_EDITOR (editor), "view",
                                       "view-zoom-fit-in", NULL);

      editor->zoom_fill_button =
        gimp_editor_add_action_button (GIMP_EDITOR (editor), "view",
                                       "view-zoom-fill", NULL);

      editor->shrink_wrap_button =
        gimp_editor_add_action_button (GIMP_EDITOR (editor), "view",
                                       "view-shrink-wrap", NULL);

      /* the zoom scale */

      hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
      gtk_box_pack_end (GTK_BOX (editor), hbox, FALSE, FALSE, 0);
      gtk_widget_show (hbox);

      editor->zoom_adjustment = gtk_adjustment_new (0.0, -8.0, 8.0,
                                                    0.5, 1.0, 0.0);

      g_signal_connect (editor->zoom_adjustment, "value-changed",
                        G_CALLBACK (gimp_navigation_editor_zoom_adj_changed),
                        editor);

      hscale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL,
                              editor->zoom_adjustment);
      gtk_scale_set_draw_value (GTK_SCALE (hscale), FALSE);
      gtk_box_pack_start (GTK_BOX (hbox), hscale, TRUE, TRUE, 0);
      gtk_widget_show (hscale);

      /* the zoom label */

      editor->zoom_label = gtk_label_new ("100%");
      gtk_label_set_width_chars (GTK_LABEL (editor->zoom_label), 7);
      gtk_box_pack_start (GTK_BOX (hbox), editor->zoom_label, FALSE, FALSE, 0);
      gtk_widget_show (editor->zoom_label);
    }

  return GTK_WIDGET (editor);
}

static void
gimp_navigation_editor_set_shell (GimpNavigationEditor *editor,
                                  GimpDisplayShell     *shell)
{
  g_return_if_fail (GIMP_IS_NAVIGATION_EDITOR (editor));
  g_return_if_fail (! shell || GIMP_IS_DISPLAY_SHELL (shell));

  if (shell == editor->shell)
    return;

  if (editor->shell)
    {
      g_signal_handlers_disconnect_by_func (editor->shell,
                                            gimp_navigation_editor_shell_infinite_canvas_notify,
                                            editor);
      g_signal_handlers_disconnect_by_func (editor->shell,
                                            gimp_navigation_editor_shell_scaled,
                                            editor);
      g_signal_handlers_disconnect_by_func (editor->shell,
                                            gimp_navigation_editor_shell_scrolled,
                                            editor);
      g_signal_handlers_disconnect_by_func (editor->shell,
                                            gimp_navigation_editor_shell_rotated,
                                            editor);
      g_signal_handlers_disconnect_by_func (editor->shell,
                                            gimp_navigation_editor_shell_reconnect,
                                            editor);

      g_signal_handlers_disconnect_by_func (editor->shell->options,
                                            gimp_navigation_editor_options_show_canvas_notify,
                                            editor);
      g_signal_handlers_disconnect_by_func (editor->shell->fullscreen_options,
                                            gimp_navigation_editor_options_show_canvas_notify,
                                            editor);
    }
  else if (shell)
    {
      gtk_widget_set_sensitive (GTK_WIDGET (editor), TRUE);
    }

  editor->shell = shell;

  if (editor->shell)
    {
      GimpImage *image = gimp_display_get_image (shell->display);

      g_clear_object (&editor->image_proxy);

      if (image)
        {
          editor->image_proxy = gimp_image_proxy_new (image);

          g_signal_connect (
            editor->image_proxy, "size-changed",
            G_CALLBACK (gimp_navigation_editor_viewable_size_changed),
            editor);
        }

      gimp_view_set_viewable (GIMP_VIEW (editor->view),
                              GIMP_VIEWABLE (editor->image_proxy));

      g_signal_connect (editor->shell, "notify::infinite-canvas",
                        G_CALLBACK (gimp_navigation_editor_shell_infinite_canvas_notify),
                        editor);
      g_signal_connect (editor->shell, "scaled",
                        G_CALLBACK (gimp_navigation_editor_shell_scaled),
                        editor);
      g_signal_connect (editor->shell, "scrolled",
                        G_CALLBACK (gimp_navigation_editor_shell_scrolled),
                        editor);
      g_signal_connect (editor->shell, "rotated",
                        G_CALLBACK (gimp_navigation_editor_shell_rotated),
                        editor);
      g_signal_connect (editor->shell, "reconnect",
                        G_CALLBACK (gimp_navigation_editor_shell_reconnect),
                        editor);

      g_signal_connect (editor->shell->options, "notify::show-canvas-boundary",
                        G_CALLBACK (gimp_navigation_editor_options_show_canvas_notify),
                        editor);
      g_signal_connect (editor->shell->fullscreen_options, "notify::show-canvas-boundary",
                        G_CALLBACK (gimp_navigation_editor_options_show_canvas_notify),
                        editor);

      gimp_navigation_editor_shell_scaled (editor->shell, editor);
    }
  else
    {
      gimp_view_set_viewable (GIMP_VIEW (editor->view), NULL);
      gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE);

      g_clear_object (&editor->image_proxy);
    }

  if (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)))
    gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)),
                            gimp_editor_get_popup_data (GIMP_EDITOR (editor)));
}

static gboolean
gimp_navigation_editor_button_release (GtkWidget        *widget,
                                       GdkEventButton   *bevent,
                                       GimpDisplayShell *shell)
{
  if (bevent->button == 1)
    {
      gtk_widget_hide (shell->nav_popup);
    }

  return FALSE;
}

static void
gimp_navigation_editor_marker_changed (GimpNavigationView   *view,
                                       gdouble               center_x,
                                       gdouble               center_y,
                                       gdouble               width,
                                       gdouble               height,
                                       GimpNavigationEditor *editor)
{
  GimpViewRenderer *renderer = GIMP_VIEW (editor->view)->renderer;

  if (editor->shell)
    {
      if (gimp_display_get_image (editor->shell->display))
        {
          GeglRectangle bounding_box;

          bounding_box = gimp_image_proxy_get_bounding_box (
            GIMP_IMAGE_PROXY (renderer->viewable));

          center_x += bounding_box.x;
          center_y += bounding_box.y;

          gimp_display_shell_scroll_center_image_xy (editor->shell,
                                                     center_x, center_y);
        }
    }
}

static void
gimp_navigation_editor_zoom (GimpNavigationView   *view,
                             GimpZoomType          direction,
                             gdouble               delta,
                             GimpNavigationEditor *editor)
{
  g_return_if_fail (direction != GIMP_ZOOM_TO);

  if (editor->shell)
    {
      if (gimp_display_get_image (editor->shell->display))
        gimp_display_shell_scale (editor->shell,
                                  direction,
                                  delta,
                                  GIMP_ZOOM_FOCUS_BEST_GUESS);
    }
}

static void
gimp_navigation_editor_scroll (GimpNavigationView   *view,
                               GdkEventScroll       *sevent,
                               GimpNavigationEditor *editor)
{
  if (editor->shell)
    {
      gdouble value_x;
      gdouble value_y;

      gimp_scroll_adjustment_values (sevent,
                                     editor->shell->hsbdata,
                                     editor->shell->vsbdata,
                                     &value_x, &value_y);

      gtk_adjustment_set_value (editor->shell->hsbdata, value_x);
      gtk_adjustment_set_value (editor->shell->vsbdata, value_y);
    }
}

static gboolean
gimp_navigation_editor_zoom_adj_changed_timeout (gpointer data)
{
  GimpNavigationEditor *editor = GIMP_NAVIGATION_EDITOR (data);
  GtkAdjustment        *adj    = editor->zoom_adjustment;

  if (gimp_display_get_image (editor->shell->display))
    gimp_display_shell_scale (editor->shell,
                              GIMP_ZOOM_TO,
                              pow (2.0, gtk_adjustment_get_value (adj)),
                              GIMP_ZOOM_FOCUS_BEST_GUESS);

  editor->scale_timeout = 0;

  return FALSE;
}

static void
gimp_navigation_editor_zoom_adj_changed (GtkAdjustment        *adj,
                                         GimpNavigationEditor *editor)
{
  if (editor->scale_timeout)
    g_source_remove (editor->scale_timeout);

  editor->scale_timeout =
    g_idle_add (gimp_navigation_editor_zoom_adj_changed_timeout,
                editor);
}

static void
gimp_navigation_editor_shell_infinite_canvas_notify (GimpDisplayShell     *shell,
                                                     const GParamSpec     *pspec,
                                                     GimpNavigationEditor *editor)
{
  gimp_navigation_editor_update_marker (editor);

  if (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)))
    gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)),
                            gimp_editor_get_popup_data (GIMP_EDITOR (editor)));
}

static void
gimp_navigation_editor_shell_scaled (GimpDisplayShell     *shell,
                                     GimpNavigationEditor *editor)
{
  if (editor->zoom_label)
    {
      gchar *str;

      g_object_get (shell->zoom,
                    "percentage", &str,
                    NULL);
      gtk_label_set_text (GTK_LABEL (editor->zoom_label), str);
      g_free (str);
    }

  if (editor->zoom_adjustment)
    {
      gdouble val;

      val = log (gimp_zoom_model_get_factor (shell->zoom)) / G_LN2;

      g_signal_handlers_block_by_func (editor->zoom_adjustment,
                                       gimp_navigation_editor_zoom_adj_changed,
                                       editor);

      gtk_adjustment_set_value (editor->zoom_adjustment, val);

      g_signal_handlers_unblock_by_func (editor->zoom_adjustment,
                                         gimp_navigation_editor_zoom_adj_changed,
                                         editor);
    }

  gimp_navigation_editor_update_marker (editor);

  if (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)))
    gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)),
                            gimp_editor_get_popup_data (GIMP_EDITOR (editor)));
}

static void
gimp_navigation_editor_shell_scrolled (GimpDisplayShell     *shell,
                                       GimpNavigationEditor *editor)
{
  gimp_navigation_editor_update_marker (editor);

  if (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)))
    gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)),
                            gimp_editor_get_popup_data (GIMP_EDITOR (editor)));
}

static void
gimp_navigation_editor_shell_rotated (GimpDisplayShell     *shell,
                                      GimpNavigationEditor *editor)
{
  gimp_navigation_editor_update_marker (editor);

  if (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)))
    gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)),
                            gimp_editor_get_popup_data (GIMP_EDITOR (editor)));
}

static void
gimp_navigation_editor_viewable_size_changed (GimpViewable         *viewable,
                                              GimpNavigationEditor *editor)
{
  gimp_navigation_editor_update_marker (editor);

  if (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)))
    gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)),
                            gimp_editor_get_popup_data (GIMP_EDITOR (editor)));
}

static void
gimp_navigation_editor_options_show_canvas_notify (GimpDisplayOptions   *options,
                                                   const GParamSpec     *pspec,
                                                   GimpNavigationEditor *editor)
{
  gimp_navigation_editor_update_marker (editor);
}

static void
gimp_navigation_editor_shell_reconnect (GimpDisplayShell     *shell,
                                        GimpNavigationEditor *editor)
{
  GimpImage *image = gimp_display_get_image (shell->display);

  g_clear_object (&editor->image_proxy);

  if (image)
    {
      editor->image_proxy = gimp_image_proxy_new (image);

      g_signal_connect (
        editor->image_proxy, "size-changed",
        G_CALLBACK (gimp_navigation_editor_viewable_size_changed),
        editor);
    }

  gimp_view_set_viewable (GIMP_VIEW (editor->view),
                          GIMP_VIEWABLE (editor->image_proxy));

  if (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)))
    gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)),
                            gimp_editor_get_popup_data (GIMP_EDITOR (editor)));
}

static void
gimp_navigation_editor_update_marker (GimpNavigationEditor *editor)
{
  GimpViewRenderer *renderer = GIMP_VIEW (editor->view)->renderer;
  GimpDisplayShell *shell    = editor->shell;

  if (renderer->dot_for_dot != shell->dot_for_dot)
    gimp_view_renderer_set_dot_for_dot (renderer, shell->dot_for_dot);

  if (renderer->viewable)
    {
      GimpNavigationView *view = GIMP_NAVIGATION_VIEW (editor->view);
      GimpImage          *image;
      GeglRectangle       bounding_box;
      gdouble             x, y;
      gdouble             w, h;

      image = gimp_image_proxy_get_image (
        GIMP_IMAGE_PROXY (renderer->viewable));

      gimp_image_proxy_set_show_all (
        GIMP_IMAGE_PROXY (renderer->viewable),
        gimp_display_shell_get_infinite_canvas (shell));

      bounding_box = gimp_image_proxy_get_bounding_box (
        GIMP_IMAGE_PROXY (renderer->viewable));

      gimp_display_shell_scroll_get_viewport (shell, &x, &y, &w, &h);
      gimp_display_shell_untransform_xy_f (shell,
                                           shell->disp_width  / 2,
                                           shell->disp_height / 2,
                                           &x, &y);

      x -= bounding_box.x;
      y -= bounding_box.y;

      gimp_navigation_view_set_marker (view,
                                       x, y, w, h,
                                       shell->flip_horizontally,
                                       shell->flip_vertically,
                                       shell->rotate_angle);

      gimp_navigation_view_set_canvas (
        view,
        gimp_display_shell_get_infinite_canvas (shell) &&
        gimp_display_shell_get_show_canvas (shell),
        -bounding_box.x,              -bounding_box.y,
        gimp_image_get_width (image), gimp_image_get_height (image));
    }
}

Messung
CHZG
829610092

¤ Dauer der Verarbeitung: 0.12 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104842
#Domains=499164