~ubuntu-branches/ubuntu/maverick/gimp/maverick-updates

« back to all changes in this revision

Viewing changes to app/display/gimpnavigationeditor.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2005-12-09 19:44:52 UTC
  • Revision ID: james.westby@ubuntu.com-20051209194452-yggpemjlofpjqyf4
Tags: upstream-2.2.9
ImportĀ upstreamĀ versionĀ 2.2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* The GIMP -- an image manipulation program
 
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 
3
 *
 
4
 * gimpnavigationeditor.c
 
5
 * Copyright (C) 2001 Michael Natterer <mitch@gimp.org>
 
6
 *
 
7
 * partly based on app/nav_window
 
8
 * Copyright (C) 1999 Andy Thomas <alt@gimp.org>
 
9
 *
 
10
 * This program is free software; you can redistribute it and/or modify
 
11
 * it under the terms of the GNU General Public License as published by
 
12
 * the Free Software Foundation; either version 2 of the License, or
 
13
 * (at your option) any later version.
 
14
 *
 
15
 * This program is distributed in the hope that it will be useful,
 
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 * GNU General Public License for more details.
 
19
 *
 
20
 * You should have received a copy of the GNU General Public License
 
21
 * along with this program; if not, write to the Free Software
 
22
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
23
 */
 
24
 
 
25
#include "config.h"
 
26
 
 
27
#include <gtk/gtk.h>
 
28
 
 
29
#include "libgimpwidgets/gimpwidgets.h"
 
30
 
 
31
#include "display-types.h"
 
32
 
 
33
#include "config/gimpdisplayconfig.h"
 
34
 
 
35
#include "core/gimp.h"
 
36
#include "core/gimpcontext.h"
 
37
#include "core/gimpimage.h"
 
38
 
 
39
#include "widgets/gimpdocked.h"
 
40
#include "widgets/gimphelp-ids.h"
 
41
#include "widgets/gimpmenufactory.h"
 
42
#include "widgets/gimpnavigationview.h"
 
43
#include "widgets/gimpuimanager.h"
 
44
#include "widgets/gimpviewrenderer.h"
 
45
 
 
46
#include "gimpdisplay.h"
 
47
#include "gimpdisplayshell.h"
 
48
#include "gimpdisplayshell-scale.h"
 
49
#include "gimpdisplayshell-scroll.h"
 
50
#include "gimpnavigationeditor.h"
 
51
 
 
52
#include "gimp-intl.h"
 
53
 
 
54
 
 
55
#define MAX_SCALE_BUF 20
 
56
 
 
57
 
 
58
static void   gimp_navigation_editor_class_init (GimpNavigationEditorClass *klass);
 
59
static void   gimp_navigation_editor_init       (GimpNavigationEditor      *editor);
 
60
 
 
61
static void   gimp_navigation_editor_docked_iface_init (GimpDockedInterface *docked_iface);
 
62
static void   gimp_navigation_editor_set_context       (GimpDocked       *docked,
 
63
                                                        GimpContext      *context);
 
64
 
 
65
static void   gimp_navigation_editor_destroy           (GtkObject          *object);
 
66
 
 
67
static GtkWidget * gimp_navigation_editor_new_private  (GimpMenuFactory    *menu_factory,
 
68
                                                        GimpDisplayShell   *shell);
 
69
 
 
70
static void     gimp_navigation_editor_set_shell       (GimpNavigationEditor *view,
 
71
                                                        GimpDisplayShell     *shell);
 
72
static gboolean gimp_navigation_editor_button_release  (GtkWidget          *widget,
 
73
                                                        GdkEventButton     *bevent,
 
74
                                                        GimpDisplayShell   *shell);
 
75
static void   gimp_navigation_editor_marker_changed    (GimpNavigationView   *view,
 
76
                                                        gdouble               x,
 
77
                                                        gdouble               y,
 
78
                                                        GimpNavigationEditor *editor);
 
79
static void   gimp_navigation_editor_zoom              (GimpNavigationView   *view,
 
80
                                                        GimpZoomType          direction,
 
81
                                                        GimpNavigationEditor *editor);
 
82
static void   gimp_navigation_editor_scroll            (GimpNavigationView   *view,
 
83
                                                        GdkScrollDirection    direction,
 
84
                                                        GimpNavigationEditor  *editor);
 
85
 
 
86
static void   gimp_navigation_editor_zoom_adj_changed  (GtkAdjustment        *adj,
 
87
                                                        GimpNavigationEditor *editor);
 
88
 
 
89
static void   gimp_navigation_editor_shell_scaled      (GimpDisplayShell     *shell,
 
90
                                                        GimpNavigationEditor *editor);
 
91
static void   gimp_navigation_editor_shell_scrolled    (GimpDisplayShell     *shell,
 
92
                                                        GimpNavigationEditor *editor);
 
93
static void   gimp_navigation_editor_shell_reconnect   (GimpDisplayShell     *shell,
 
94
                                                        GimpNavigationEditor *editor);
 
95
static void   gimp_navigation_editor_update_marker     (GimpNavigationEditor *editor);
 
96
 
 
97
 
 
98
static GimpEditorClass *parent_class = NULL;
 
99
 
 
100
 
 
101
GType
 
102
gimp_navigation_editor_get_type (void)
 
103
{
 
104
  static GType type = 0;
 
105
 
 
106
  if (! type)
 
107
    {
 
108
      static const GTypeInfo editor_info =
 
109
      {
 
110
        sizeof (GimpNavigationEditorClass),
 
111
        NULL,           /* base_init */
 
112
        NULL,           /* base_finalize */
 
113
        (GClassInitFunc) gimp_navigation_editor_class_init,
 
114
        NULL,           /* class_finalize */
 
115
        NULL,           /* class_navigation */
 
116
        sizeof (GimpNavigationEditor),
 
117
        0,              /* n_preallocs */
 
118
        (GInstanceInitFunc) gimp_navigation_editor_init,
 
119
      };
 
120
      static const GInterfaceInfo docked_iface_info =
 
121
      {
 
122
        (GInterfaceInitFunc) gimp_navigation_editor_docked_iface_init,
 
123
        NULL,           /* iface_finalize */
 
124
        NULL            /* iface_data     */
 
125
      };
 
126
 
 
127
      type = g_type_register_static (GIMP_TYPE_EDITOR,
 
128
                                     "GimpNavigationEditor",
 
129
                                     &editor_info, 0);
 
130
 
 
131
      g_type_add_interface_static (type, GIMP_TYPE_DOCKED,
 
132
                                   &docked_iface_info);
 
133
    }
 
134
 
 
135
  return type;
 
136
}
 
137
 
 
138
static void
 
139
gimp_navigation_editor_class_init (GimpNavigationEditorClass *klass)
 
140
{
 
141
  GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
 
142
 
 
143
  parent_class = g_type_class_peek_parent (klass);
 
144
 
 
145
  gtk_object_class->destroy = gimp_navigation_editor_destroy;
 
146
}
 
147
 
 
148
static void
 
149
gimp_navigation_editor_init (GimpNavigationEditor *editor)
 
150
{
 
151
  GtkWidget *frame;
 
152
 
 
153
  editor->shell = NULL;
 
154
 
 
155
  frame = gtk_frame_new (NULL);
 
156
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
 
157
  gtk_box_pack_start (GTK_BOX (editor), frame, TRUE, TRUE, 0);
 
158
  gtk_widget_show (frame);
 
159
 
 
160
  editor->view = gimp_view_new_by_types (GIMP_TYPE_NAVIGATION_VIEW,
 
161
                                         GIMP_TYPE_IMAGE,
 
162
                                         GIMP_VIEW_SIZE_MEDIUM, 0, TRUE);
 
163
  gtk_container_add (GTK_CONTAINER (frame), editor->view);
 
164
  gtk_widget_show (editor->view);
 
165
 
 
166
  g_signal_connect (editor->view, "marker_changed",
 
167
                    G_CALLBACK (gimp_navigation_editor_marker_changed),
 
168
                    editor);
 
169
  g_signal_connect (editor->view, "zoom",
 
170
                    G_CALLBACK (gimp_navigation_editor_zoom),
 
171
                    editor);
 
172
  g_signal_connect (editor->view, "scroll",
 
173
                    G_CALLBACK (gimp_navigation_editor_scroll),
 
174
                    editor);
 
175
 
 
176
  gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE);
 
177
}
 
178
 
 
179
static void
 
180
gimp_navigation_editor_docked_iface_init (GimpDockedInterface *docked_iface)
 
181
{
 
182
  docked_iface->set_context = gimp_navigation_editor_set_context;
 
183
}
 
184
 
 
185
static void
 
186
gimp_navigation_editor_context_changed (GimpContext          *context,
 
187
                                        GimpDisplay          *gdisp,
 
188
                                        GimpNavigationEditor *editor)
 
189
{
 
190
  GimpDisplayShell *shell = NULL;
 
191
 
 
192
  if (gdisp)
 
193
    shell = GIMP_DISPLAY_SHELL (gdisp->shell);
 
194
 
 
195
  gimp_navigation_editor_set_shell (editor, shell);
 
196
}
 
197
 
 
198
static void
 
199
gimp_navigation_editor_set_context (GimpDocked  *docked,
 
200
                                    GimpContext *context)
 
201
{
 
202
  GimpNavigationEditor *editor  = GIMP_NAVIGATION_EDITOR (docked);
 
203
  GimpDisplay          *gdisp = NULL;
 
204
  GimpDisplayShell     *shell = NULL;
 
205
 
 
206
  if (editor->context)
 
207
    {
 
208
      g_signal_handlers_disconnect_by_func (editor->context,
 
209
                                            gimp_navigation_editor_context_changed,
 
210
                                            editor);
 
211
    }
 
212
 
 
213
  editor->context = context;
 
214
 
 
215
  if (context)
 
216
    {
 
217
      g_signal_connect (context, "display_changed",
 
218
                        G_CALLBACK (gimp_navigation_editor_context_changed),
 
219
                        editor);
 
220
 
 
221
      gdisp = gimp_context_get_display (context);
 
222
    }
 
223
 
 
224
  if (gdisp)
 
225
    shell = GIMP_DISPLAY_SHELL (gdisp->shell);
 
226
 
 
227
  gimp_navigation_editor_set_shell (editor, shell);
 
228
}
 
229
 
 
230
static void
 
231
gimp_navigation_editor_destroy (GtkObject *object)
 
232
{
 
233
  GimpNavigationEditor *editor = GIMP_NAVIGATION_EDITOR (object);
 
234
 
 
235
  if (editor->shell)
 
236
    gimp_navigation_editor_set_shell (editor, NULL);
 
237
 
 
238
  GTK_OBJECT_CLASS (parent_class)->destroy (object);
 
239
}
 
240
 
 
241
 
 
242
/*  public functions  */
 
243
 
 
244
GtkWidget *
 
245
gimp_navigation_editor_new (GimpMenuFactory *menu_factory)
 
246
{
 
247
  return gimp_navigation_editor_new_private (menu_factory, NULL);
 
248
}
 
249
 
 
250
void
 
251
gimp_navigation_editor_popup (GimpDisplayShell *shell,
 
252
                              GtkWidget        *widget,
 
253
                              gint              click_x,
 
254
                              gint              click_y)
 
255
{
 
256
  GimpNavigationEditor *editor;
 
257
  GimpNavigationView   *view;
 
258
  GdkScreen            *screen;
 
259
  gint                  x, y;
 
260
  gint                  x_org, y_org;
 
261
 
 
262
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
 
263
  g_return_if_fail (GTK_IS_WIDGET (widget));
 
264
 
 
265
  if (! shell->nav_popup)
 
266
    {
 
267
      GtkWidget *frame;
 
268
 
 
269
      shell->nav_popup = gtk_window_new (GTK_WINDOW_POPUP);
 
270
 
 
271
      frame = gtk_frame_new (NULL);
 
272
      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
 
273
      gtk_container_add (GTK_CONTAINER (shell->nav_popup), frame);
 
274
      gtk_widget_show (frame);
 
275
 
 
276
      editor =
 
277
        GIMP_NAVIGATION_EDITOR (gimp_navigation_editor_new_private (NULL,
 
278
                                                                    shell));
 
279
      gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (editor));
 
280
      gtk_widget_show (GTK_WIDGET (editor));
 
281
 
 
282
      g_signal_connect (editor->view, "button_release_event",
 
283
                        G_CALLBACK (gimp_navigation_editor_button_release),
 
284
                        shell);
 
285
    }
 
286
  else
 
287
    {
 
288
      editor = GIMP_NAVIGATION_EDITOR (GTK_BIN (GTK_BIN (shell->nav_popup)->child)->child);
 
289
    }
 
290
 
 
291
  screen = gtk_widget_get_screen (widget);
 
292
 
 
293
  gtk_window_set_screen (GTK_WINDOW (shell->nav_popup), screen);
 
294
 
 
295
  view = GIMP_NAVIGATION_VIEW (editor->view);
 
296
 
 
297
  /* decide where to put the popup */
 
298
  gdk_window_get_origin (widget->window, &x_org, &y_org);
 
299
 
 
300
#define BORDER_PEN_WIDTH  3
 
301
 
 
302
  x = (x_org + click_x -
 
303
       view->p_x -
 
304
       0.5 * (view->p_width  - BORDER_PEN_WIDTH) -
 
305
       2   * widget->style->xthickness);
 
306
 
 
307
  y = (y_org + click_y -
 
308
       view->p_y -
 
309
       0.5 * (view->p_height - BORDER_PEN_WIDTH) -
 
310
       2   * widget->style->ythickness);
 
311
 
 
312
  /* If the popup doesn't fit into the screen, we have a problem.
 
313
   * We move the popup onscreen and risk that the pointer is not
 
314
   * in the square representing the viewable area anymore. Moving
 
315
   * the pointer will make the image scroll by a large amount,
 
316
   * but then it works as usual. Probably better than a popup that
 
317
   * is completely unusable in the lower right of the screen.
 
318
   *
 
319
   * Warping the pointer would be another solution ...
 
320
   */
 
321
 
 
322
  x = CLAMP (x, 0, (gdk_screen_get_width (screen)  -
 
323
                    GIMP_VIEW (view)->renderer->width  -
 
324
                    4 * widget->style->xthickness));
 
325
  y = CLAMP (y, 0, (gdk_screen_get_height (screen) -
 
326
                    GIMP_VIEW (view)->renderer->height -
 
327
                    4 * widget->style->ythickness));
 
328
 
 
329
  gtk_window_move (GTK_WINDOW (shell->nav_popup), x, y);
 
330
  gtk_widget_show (shell->nav_popup);
 
331
 
 
332
  gdk_flush ();
 
333
 
 
334
  /* fill in then grab pointer */
 
335
  view->motion_offset_x = 0.5 * (view->p_width  - BORDER_PEN_WIDTH);
 
336
  view->motion_offset_y = 0.5 * (view->p_height - BORDER_PEN_WIDTH);
 
337
 
 
338
#undef BORDER_PEN_WIDTH
 
339
 
 
340
  gimp_navigation_view_grab_pointer (view);
 
341
}
 
342
 
 
343
 
 
344
/*  private functions  */
 
345
 
 
346
static GtkWidget *
 
347
gimp_navigation_editor_new_private (GimpMenuFactory  *menu_factory,
 
348
                                    GimpDisplayShell *shell)
 
349
{
 
350
  GimpNavigationEditor *editor;
 
351
 
 
352
  g_return_val_if_fail (menu_factory == NULL ||
 
353
                        GIMP_IS_MENU_FACTORY (menu_factory), NULL);
 
354
  g_return_val_if_fail (shell == NULL || GIMP_IS_DISPLAY_SHELL (shell), NULL);
 
355
  g_return_val_if_fail (menu_factory || shell, NULL);
 
356
 
 
357
  if (shell)
 
358
    {
 
359
      GimpDisplayConfig *config;
 
360
      GimpView          *view;
 
361
 
 
362
      editor = g_object_new (GIMP_TYPE_NAVIGATION_EDITOR, NULL);
 
363
 
 
364
      config = GIMP_DISPLAY_CONFIG (shell->gdisp->gimage->gimp->config);
 
365
      view   = GIMP_VIEW (editor->view);
 
366
 
 
367
      gimp_view_renderer_set_size (view->renderer,
 
368
                                   config->nav_preview_size * 3,
 
369
                                   view->renderer->border_width);
 
370
 
 
371
      gimp_navigation_editor_set_shell (editor, shell);
 
372
    }
 
373
  else
 
374
    {
 
375
      GtkWidget *hscale;
 
376
 
 
377
      editor = g_object_new (GIMP_TYPE_NAVIGATION_EDITOR,
 
378
                             "menu-factory",    menu_factory,
 
379
                             "menu-identifier", "<NavigationEditor>",
 
380
                             NULL);
 
381
 
 
382
      gtk_widget_set_size_request (editor->view,
 
383
                                   GIMP_VIEW_SIZE_HUGE,
 
384
                                   GIMP_VIEW_SIZE_HUGE);
 
385
      gimp_view_set_expand (GIMP_VIEW (editor->view), TRUE);
 
386
 
 
387
      /* the editor buttons */
 
388
 
 
389
      editor->zoom_out_button =
 
390
        gimp_editor_add_action_button (GIMP_EDITOR (editor), "view",
 
391
                                       "view-zoom-out", NULL);
 
392
 
 
393
      editor->zoom_in_button =
 
394
        gimp_editor_add_action_button (GIMP_EDITOR (editor), "view",
 
395
                                       "view-zoom-in", NULL);
 
396
 
 
397
      editor->zoom_100_button =
 
398
        gimp_editor_add_action_button (GIMP_EDITOR (editor), "view",
 
399
                                       "view-zoom-1-1", NULL);
 
400
 
 
401
      editor->zoom_fit_in_button =
 
402
        gimp_editor_add_action_button (GIMP_EDITOR (editor), "view",
 
403
                                       "view-zoom-fit-in", NULL);
 
404
 
 
405
      editor->zoom_fit_to_button =
 
406
        gimp_editor_add_action_button (GIMP_EDITOR (editor), "view",
 
407
                                       "view-zoom-fit-to", NULL);
 
408
 
 
409
      editor->shrink_wrap_button =
 
410
        gimp_editor_add_action_button (GIMP_EDITOR (editor), "view",
 
411
                                       "view-shrink-wrap", NULL);
 
412
 
 
413
      /* the zoom scale */
 
414
 
 
415
      editor->zoom_adjustment =
 
416
        GTK_ADJUSTMENT (gtk_adjustment_new (0.0, -8.0, 8.0, 0.5, 1.0, 0.0));
 
417
 
 
418
      g_signal_connect (editor->zoom_adjustment, "value_changed",
 
419
                        G_CALLBACK (gimp_navigation_editor_zoom_adj_changed),
 
420
                        editor);
 
421
 
 
422
      hscale = gtk_hscale_new (GTK_ADJUSTMENT (editor->zoom_adjustment));
 
423
      gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_DELAYED);
 
424
      gtk_scale_set_draw_value (GTK_SCALE (hscale), FALSE);
 
425
      gtk_scale_set_digits (GTK_SCALE (hscale), 2);
 
426
      gtk_box_pack_end (GTK_BOX (editor), hscale, FALSE, FALSE, 0);
 
427
      gtk_widget_show (hscale);
 
428
 
 
429
      /* the zoom label */
 
430
 
 
431
      editor->zoom_label = gtk_label_new ("100%");
 
432
      gtk_box_pack_end (GTK_BOX (editor), editor->zoom_label, FALSE, FALSE, 0);
 
433
      gtk_widget_show (editor->zoom_label);
 
434
 
 
435
      /* eek */
 
436
      {
 
437
        GtkRequisition requisition;
 
438
 
 
439
        gtk_widget_size_request (editor->zoom_label, &requisition);
 
440
        gtk_widget_set_size_request (editor->zoom_label,
 
441
                                     4 * requisition.width,
 
442
                                     requisition.height);
 
443
      }
 
444
    }
 
445
 
 
446
  gimp_view_renderer_set_background (GIMP_VIEW (editor->view)->renderer,
 
447
                                     GIMP_STOCK_TEXTURE);
 
448
 
 
449
  return GTK_WIDGET (editor);
 
450
}
 
451
 
 
452
static void
 
453
gimp_navigation_editor_set_shell (GimpNavigationEditor *editor,
 
454
                                  GimpDisplayShell     *shell)
 
455
{
 
456
  g_return_if_fail (GIMP_IS_NAVIGATION_EDITOR (editor));
 
457
  g_return_if_fail (! shell || GIMP_IS_DISPLAY_SHELL (shell));
 
458
 
 
459
  if (shell == editor->shell)
 
460
    return;
 
461
 
 
462
  if (editor->shell)
 
463
    {
 
464
      g_signal_handlers_disconnect_by_func (editor->shell,
 
465
                                            gimp_navigation_editor_shell_scaled,
 
466
                                            editor);
 
467
      g_signal_handlers_disconnect_by_func (editor->shell,
 
468
                                            gimp_navigation_editor_shell_scrolled,
 
469
                                            editor);
 
470
      g_signal_handlers_disconnect_by_func (editor->shell,
 
471
                                            gimp_navigation_editor_shell_reconnect,
 
472
                                            editor);
 
473
    }
 
474
  else if (shell)
 
475
    {
 
476
      gtk_widget_set_sensitive (GTK_WIDGET (editor), TRUE);
 
477
    }
 
478
 
 
479
  editor->shell = shell;
 
480
 
 
481
  if (editor->shell)
 
482
    {
 
483
      gimp_view_set_viewable (GIMP_VIEW (editor->view),
 
484
                              GIMP_VIEWABLE (shell->gdisp->gimage));
 
485
 
 
486
      g_signal_connect (editor->shell, "scaled",
 
487
                        G_CALLBACK (gimp_navigation_editor_shell_scaled),
 
488
                        editor);
 
489
      g_signal_connect (editor->shell, "scrolled",
 
490
                        G_CALLBACK (gimp_navigation_editor_shell_scrolled),
 
491
                        editor);
 
492
      g_signal_connect (editor->shell, "reconnect",
 
493
                        G_CALLBACK (gimp_navigation_editor_shell_reconnect),
 
494
                        editor);
 
495
 
 
496
      gimp_navigation_editor_shell_scaled (editor->shell, editor);
 
497
    }
 
498
  else
 
499
    {
 
500
      gimp_view_set_viewable (GIMP_VIEW (editor->view), NULL);
 
501
      gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE);
 
502
    }
 
503
 
 
504
  if (GIMP_EDITOR (editor)->ui_manager)
 
505
    gimp_ui_manager_update (GIMP_EDITOR (editor)->ui_manager,
 
506
                            GIMP_EDITOR (editor)->popup_data);
 
507
}
 
508
 
 
509
static gboolean
 
510
gimp_navigation_editor_button_release (GtkWidget        *widget,
 
511
                                       GdkEventButton   *bevent,
 
512
                                       GimpDisplayShell *shell)
 
513
{
 
514
  if (bevent->button == 1)
 
515
    {
 
516
      gtk_widget_hide (shell->nav_popup);
 
517
    }
 
518
 
 
519
  return FALSE;
 
520
}
 
521
 
 
522
static void
 
523
gimp_navigation_editor_marker_changed (GimpNavigationView   *view,
 
524
                                       gdouble               x,
 
525
                                       gdouble               y,
 
526
                                       GimpNavigationEditor *editor)
 
527
{
 
528
  if (editor->shell)
 
529
    {
 
530
      gdouble xratio;
 
531
      gdouble yratio;
 
532
      gint    xoffset;
 
533
      gint    yoffset;
 
534
 
 
535
      xratio = SCALEFACTOR_X (editor->shell);
 
536
      yratio = SCALEFACTOR_Y (editor->shell);
 
537
 
 
538
      xoffset = RINT (x * xratio - editor->shell->offset_x);
 
539
      yoffset = RINT (y * yratio - editor->shell->offset_y);
 
540
 
 
541
      gimp_display_shell_scroll (editor->shell, xoffset, yoffset);
 
542
    }
 
543
}
 
544
 
 
545
static void
 
546
gimp_navigation_editor_zoom (GimpNavigationView   *view,
 
547
                             GimpZoomType          direction,
 
548
                             GimpNavigationEditor *editor)
 
549
{
 
550
  g_return_if_fail (direction != GIMP_ZOOM_TO);
 
551
 
 
552
  if (editor->shell)
 
553
    {
 
554
      gimp_display_shell_scale (editor->shell, direction, 0.0);
 
555
    }
 
556
}
 
557
 
 
558
static void
 
559
gimp_navigation_editor_scroll (GimpNavigationView   *view,
 
560
                               GdkScrollDirection    direction,
 
561
                               GimpNavigationEditor *editor)
 
562
{
 
563
  if (editor->shell)
 
564
    {
 
565
      GtkAdjustment *adj = NULL;
 
566
      gdouble        value;
 
567
 
 
568
      switch (direction)
 
569
        {
 
570
        case GDK_SCROLL_LEFT:
 
571
        case GDK_SCROLL_RIGHT:
 
572
          adj = editor->shell->hsbdata;
 
573
          break;
 
574
 
 
575
        case GDK_SCROLL_UP:
 
576
        case GDK_SCROLL_DOWN:
 
577
          adj = editor->shell->vsbdata;
 
578
          break;
 
579
        }
 
580
 
 
581
      g_assert (adj != NULL);
 
582
 
 
583
      value = adj->value;
 
584
 
 
585
      switch (direction)
 
586
        {
 
587
        case GDK_SCROLL_LEFT:
 
588
        case GDK_SCROLL_UP:
 
589
          value -= adj->page_increment / 2;
 
590
          break;
 
591
 
 
592
        case GDK_SCROLL_RIGHT:
 
593
        case GDK_SCROLL_DOWN:
 
594
          value += adj->page_increment / 2;
 
595
          break;
 
596
        }
 
597
 
 
598
      value = CLAMP (value, adj->lower, adj->upper - adj->page_size);
 
599
 
 
600
      gtk_adjustment_set_value (adj, value);
 
601
    }
 
602
}
 
603
 
 
604
static void
 
605
gimp_navigation_editor_zoom_adj_changed (GtkAdjustment        *adj,
 
606
                                         GimpNavigationEditor *editor)
 
607
{
 
608
  gimp_display_shell_scale (editor->shell, GIMP_ZOOM_TO,
 
609
                            pow (2.0, adj->value));
 
610
}
 
611
 
 
612
static void
 
613
gimp_navigation_editor_shell_scaled (GimpDisplayShell     *shell,
 
614
                                     GimpNavigationEditor *editor)
 
615
{
 
616
  if (editor->zoom_label)
 
617
    {
 
618
      gchar scale_str[MAX_SCALE_BUF];
 
619
 
 
620
      /* Update the zoom scale string */
 
621
      g_snprintf (scale_str, sizeof (scale_str),
 
622
                  shell->scale >= 0.15 ? "%.0f%%" : "%.2f%%",
 
623
                  editor->shell->scale * 100);
 
624
 
 
625
      gtk_label_set_text (GTK_LABEL (editor->zoom_label), scale_str);
 
626
    }
 
627
 
 
628
  if (editor->zoom_adjustment)
 
629
    {
 
630
      gdouble val;
 
631
 
 
632
      val = log (CLAMP (editor->shell->scale, 1.0 / 256, 256.0) ) / G_LN2;
 
633
 
 
634
      g_signal_handlers_block_by_func (editor->zoom_adjustment,
 
635
                                       gimp_navigation_editor_zoom_adj_changed,
 
636
                                       editor);
 
637
 
 
638
      gtk_adjustment_set_value (editor->zoom_adjustment, val);
 
639
 
 
640
      g_signal_handlers_unblock_by_func (editor->zoom_adjustment,
 
641
                                         gimp_navigation_editor_zoom_adj_changed,
 
642
                                         editor);
 
643
    }
 
644
 
 
645
  gimp_navigation_editor_update_marker (editor);
 
646
 
 
647
  if (GIMP_EDITOR (editor)->ui_manager)
 
648
    gimp_ui_manager_update (GIMP_EDITOR (editor)->ui_manager,
 
649
                            GIMP_EDITOR (editor)->popup_data);
 
650
}
 
651
 
 
652
static void
 
653
gimp_navigation_editor_shell_scrolled (GimpDisplayShell     *shell,
 
654
                                       GimpNavigationEditor *editor)
 
655
{
 
656
  gimp_navigation_editor_update_marker (editor);
 
657
 
 
658
  if (GIMP_EDITOR (editor)->ui_manager)
 
659
    gimp_ui_manager_update (GIMP_EDITOR (editor)->ui_manager,
 
660
                            GIMP_EDITOR (editor)->popup_data);
 
661
}
 
662
 
 
663
static void
 
664
gimp_navigation_editor_shell_reconnect (GimpDisplayShell     *shell,
 
665
                                        GimpNavigationEditor *editor)
 
666
{
 
667
  gimp_view_set_viewable (GIMP_VIEW (editor->view),
 
668
                          GIMP_VIEWABLE (shell->gdisp->gimage));
 
669
 
 
670
  if (GIMP_EDITOR (editor)->ui_manager)
 
671
    gimp_ui_manager_update (GIMP_EDITOR (editor)->ui_manager,
 
672
                            GIMP_EDITOR (editor)->popup_data);
 
673
}
 
674
 
 
675
static void
 
676
gimp_navigation_editor_update_marker (GimpNavigationEditor *editor)
 
677
{
 
678
  GimpViewRenderer *renderer;
 
679
  gdouble           xratio;
 
680
  gdouble           yratio;
 
681
 
 
682
  renderer = GIMP_VIEW (editor->view)->renderer;
 
683
 
 
684
  xratio = SCALEFACTOR_X (editor->shell);
 
685
  yratio = SCALEFACTOR_Y (editor->shell);
 
686
 
 
687
  if (renderer->dot_for_dot != editor->shell->dot_for_dot)
 
688
    gimp_view_renderer_set_dot_for_dot (renderer,
 
689
                                        editor->shell->dot_for_dot);
 
690
 
 
691
  gimp_navigation_view_set_marker (GIMP_NAVIGATION_VIEW (editor->view),
 
692
                                   editor->shell->offset_x    / xratio,
 
693
                                   editor->shell->offset_y    / yratio,
 
694
                                   editor->shell->disp_width  / xratio,
 
695
                                   editor->shell->disp_height / yratio);
 
696
}