tmf/lttng: Remove unneeded (non-Javadoc) comments
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / uml2sd / ScrollView.java
CommitLineData
73005152 1/**********************************************************************
c8422608 2 * Copyright (c) 2005, 2013 IBM Corporation, Ericsson
73005152
BH
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
a55887ca
AM
7 *
8 * Contributors:
c8422608
AM
9 * IBM - Initial API and implementation
10 * Bernd Hufmann - Updated for TMF
73005152 11 **********************************************************************/
c8422608 12
73005152
BH
13package org.eclipse.linuxtools.tmf.ui.views.uml2sd;
14
15import java.util.Timer;
16import java.util.TimerTask;
17
18import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.SDMessages;
19import org.eclipse.swt.SWT;
20import org.eclipse.swt.events.ControlListener;
21import org.eclipse.swt.events.FocusEvent;
22import org.eclipse.swt.events.FocusListener;
23import org.eclipse.swt.events.KeyEvent;
24import org.eclipse.swt.events.KeyListener;
25import org.eclipse.swt.events.MouseEvent;
26import org.eclipse.swt.events.MouseListener;
27import org.eclipse.swt.events.MouseMoveListener;
28import org.eclipse.swt.events.MouseTrackListener;
29import org.eclipse.swt.events.PaintEvent;
30import org.eclipse.swt.events.PaintListener;
31import org.eclipse.swt.events.SelectionEvent;
32import org.eclipse.swt.events.SelectionListener;
33import org.eclipse.swt.events.TypedEvent;
34import org.eclipse.swt.graphics.Color;
35import org.eclipse.swt.graphics.Cursor;
36import org.eclipse.swt.graphics.GC;
37import org.eclipse.swt.graphics.ImageData;
38import org.eclipse.swt.graphics.PaletteData;
39import org.eclipse.swt.graphics.Point;
40import org.eclipse.swt.graphics.RGB;
41import org.eclipse.swt.graphics.Rectangle;
42import org.eclipse.swt.widgets.Button;
43import org.eclipse.swt.widgets.Canvas;
44import org.eclipse.swt.widgets.Composite;
45import org.eclipse.swt.widgets.Control;
46import org.eclipse.swt.widgets.Display;
47import org.eclipse.swt.widgets.Layout;
48import org.eclipse.swt.widgets.ScrollBar;
49import org.eclipse.swt.widgets.Scrollable;
50import org.eclipse.swt.widgets.Shell;
51
52/**
a55887ca 53 * ScrollView widget provides a scrolling area with on-demand scroll bars.
df0b8ff4 54 * Overview scrollable panel can be used (@see setOverviewEnabled()).
a55887ca 55 *
73005152
BH
56 * @author Eric Miravete
57 * @version 1.0
58 */
59public class ScrollView extends Composite {
a55887ca 60
df0b8ff4
BH
61 // ------------------------------------------------------------------------
62 // Attributes
63 // ------------------------------------------------------------------------
64
a55887ca 65 // Value for scroll bar mode, default is AUTO
df0b8ff4
BH
66 /**
67 * Scroll bar mode AUTO
68 */
73005152 69 public static final int AUTO = 0;
df0b8ff4
BH
70 /**
71 * Scroll bar mode ALWAYS_ON
72 */
73005152 73 public static final int ALWAYS_ON = 1;
df0b8ff4
BH
74 /**
75 * Scroll bar mode ALWAYS_OFF
76 */
77 public static final int ALWAYS_OFF = 2;
78 /**
a55887ca 79 * Bit mask for visible vertical scroll bar
df0b8ff4
BH
80 */
81 public static final int VBAR = 0x01;
82 /**
a55887ca 83 * Bit mask for visible horizontal scroll bar
df0b8ff4
BH
84 */
85 public static final int HBAR = 0x02;
86 /**
eb63f5ff 87 * Value of the contents height property.
df0b8ff4 88 */
eb63f5ff 89 protected int fContentsHeight = 0;
df0b8ff4 90 /**
eb63f5ff 91 * Value of the contents width property.
df0b8ff4 92 */
eb63f5ff 93 protected int fContentsWidth = 0;
df0b8ff4 94 /**
a55887ca 95 * Value of the contents x coordinate property
df0b8ff4 96 */
eb63f5ff 97 protected int fContentsX = 0;
df0b8ff4 98 /**
a55887ca 99 * Value of the contents y coordinate property
df0b8ff4 100 */
eb63f5ff 101 protected int fContentsY = 0;
df0b8ff4 102 /**
a55887ca
AM
103 * Scroll bar mode of horizontal scroll bar.
104 */
eb63f5ff 105 protected int fHorScrollbarMode = AUTO;
df0b8ff4 106 /**
a55887ca
AM
107 * Scroll bar mode of vertical scroll bar.
108 */
eb63f5ff 109 protected int fVertScrollbarMode = AUTO;
df0b8ff4
BH
110 /**
111 * Increment for the horizontal scroll bar.
112 */
eb63f5ff 113 protected int fHorScrollbarIncrement = 10;
df0b8ff4
BH
114 /**
115 * Increment for the vertical scroll bar.
116 */
eb63f5ff 117 protected int fVertScrollbarIncrement = 10;
df0b8ff4
BH
118 /**
119 * Flag whether auto scroll is enabled or not.
120 */
eb63f5ff 121 protected boolean fAutoScrollEnabled = true;
df0b8ff4
BH
122 /**
123 * Value of the auto scroll period.
124 */
eb63f5ff 125 protected int fAutoScrollPeriod = 75;
df0b8ff4
BH
126 /**
127 * The local paint listener reference.
128 */
eb63f5ff 129 protected PaintListener fLocalPaintListener = null;
df0b8ff4
BH
130 /**
131 * The local mouse move listener reference.
132 */
eb63f5ff 133 protected MouseMoveListener fLocalMouseMoveListener = null;
df0b8ff4
BH
134 /**
135 * The local mouse listener reference.
136 */
eb63f5ff 137 protected MouseListener fLocalMouseListener = null;
df0b8ff4
BH
138 /**
139 * The local control listener reference.
140 */
eb63f5ff 141 protected ControlListener fLocalControlListener = null;
df0b8ff4
BH
142 /**
143 * The local key listener reference.
144 */
eb63f5ff 145 protected KeyListener fLocalKeyListener = null;
df0b8ff4
BH
146 // Canvas for vertical/horizontal Scroll Bar only ... because new ScrollBar() does works.
147 /**
148 * Canvas for horizontal scroll bar.
149 */
eb63f5ff 150 protected Canvas fHorScrollBar;
df0b8ff4
BH
151 /**
152 * Canvas for vertical scroll bar.
153 */
eb63f5ff 154 protected Canvas fVertScrollBar;
df0b8ff4
BH
155 /**
156 * Canvas for the view control.
157 */
eb63f5ff 158 protected Canvas fViewControl;
df0b8ff4 159 /**
a55887ca 160 * Control used in the bottom right corner @see setCornerControl() and @see setOverviewEnabled(true)
df0b8ff4 161 */
eb63f5ff 162 protected Control fCornerControl;
df0b8ff4
BH
163 /**
164 * Size of overview widget.
165 */
eb63f5ff
BH
166 protected int fOverviewSize = 100; // default size for overview
167 /**
a55887ca 168 * Timer for auto_scroll feature
eb63f5ff
BH
169 */
170 protected AutoScroll fAutoScroll = null;
a55887ca
AM
171 /**
172 * TimerTask for auto_scroll feature !=null when auto scroll is running
eb63f5ff
BH
173 */
174 protected Timer fAutoScrollTimer = null;
a55887ca
AM
175 /**
176 * where mouse down appear on contents area (x coordinate)
eb63f5ff
BH
177 */
178 protected int fMouseDownX = -1;
a55887ca
AM
179 /**
180 * where mouse down appear on contents area (y coordinate)
eb63f5ff
BH
181 */
182 protected int fMousDownY = -1;
73005152 183
a55887ca 184
df0b8ff4
BH
185 // ------------------------------------------------------------------------
186 // Constructors
187 // ------------------------------------------------------------------------
188
73005152
BH
189 /**
190 * Create a ScrollView, child of composite c. Both scroll bar have the mode AUTO. Auto scroll feature is enabled
191 * using a delay of 250ms. Overview feature is not enabled by default (use setOverviewEnabled()).
a55887ca 192 *
df0b8ff4
BH
193 * @param c The parent composite
194 * @param style The SWT style bits @see SWT
73005152
BH
195 */
196 public ScrollView(Composite c, int style) {
197 this(c, style, true);
198 }
199
200 /**
201 * Create a ScrollView, child of composite c. Both scroll bar have the mode AUTO. Auto scroll feature is enabled
202 * using a delay of 250ms. Overview feature is not enabled by default (use setOverviewEnabled()).
a55887ca 203 *
df0b8ff4
BH
204 * @param c The parent composite.
205 * @param style The SWT style bits @see SWT
206 * @param mouseWheel Flag to force scrollView to handles mouse wheel
73005152
BH
207 */
208 public ScrollView(Composite c, int style, boolean mouseWheel) {
209 super(c, SWT.NONE); // style&(~(SWT.H_SCROLL|SWT.V_SCROLL)));
210
eb63f5ff 211 fHorScrollBar = new Canvas(this, SWT.H_SCROLL);
df0b8ff4 212 if (mouseWheel) {
73005152 213 // force scroll bar to get mouse wheel, those scrollbar will be hidden
eb63f5ff 214 fViewControl = new Canvas(this, style | SWT.H_SCROLL | SWT.V_SCROLL);
df0b8ff4 215 } else {
eb63f5ff 216 fViewControl = new Canvas(this, style);
df0b8ff4 217 }
eb63f5ff
BH
218 fViewControl.setBackground(getBackground());
219 // hide scroll bar as their are replaced by fHorScrollBar and fVertScrollBar.
73005152 220 if (mouseWheel) {
eb63f5ff
BH
221 fViewControl.getVerticalBar().setVisible(false);
222 fViewControl.getHorizontalBar().setVisible(false);
73005152 223 }
eb63f5ff
BH
224 fVertScrollBar = new Canvas(this, SWT.V_SCROLL);
225 // make fVerScrollBar able to receive mouse wheel
226 // does not help as we can't set a MouseListener on fVerScrollBar.getVerticalBar()
73005152 227 // to set focus on viewcontrol_
eb63f5ff 228 // fVerScrollBar.addKeyListener( new KeyAdapter() {});
73005152
BH
229
230 setLayout(new SVLayout());
231
eb63f5ff 232 fLocalPaintListener = new PaintListener() {
73005152
BH
233 @Override
234 public void paintControl(PaintEvent event) {
235 // use clipping, to reduce cost of paint.
236 Rectangle r = event.gc.getClipping();
237 int cx = viewToContentsX(r.x);
238 int cy = viewToContentsY(r.y);
239 drawContents(event.gc, cx, cy, r.width, r.height);
240 }
241 };
eb63f5ff 242 fViewControl.addPaintListener(fLocalPaintListener);
73005152 243
eb63f5ff 244 fLocalMouseMoveListener = new MouseMoveListener() {
73005152
BH
245 @Override
246 public void mouseMove(MouseEvent e) {
247 int ox = e.x, oy = e.y;
248 e.x = viewToContentsX(e.x);
249 e.y = viewToContentsY(e.y);
250 contentsMouseMoveEvent(e);
251 e.x = ox;
252 e.y = oy;
253 }
254 };
255
eb63f5ff 256 fViewControl.addMouseMoveListener(fLocalMouseMoveListener);
73005152
BH
257
258 MouseTrackListener localMouseTrackListener = new MouseTrackListener() {
259 @Override
260 public void mouseEnter(MouseEvent e) {
261 int ox = e.x, oy = e.y;
262 e.x = viewToContentsX(e.x);
263 e.y = viewToContentsY(e.y);
264 contentsMouseEnter(e);
265 e.x = ox;
266 e.y = oy;
267 }
268
269 @Override
270 public void mouseHover(MouseEvent e) {
271 int ox = e.x, oy = e.y;
272 e.x = viewToContentsX(e.x);
273 e.y = viewToContentsY(e.y);
274 contentsMouseHover(e);
275 e.x = ox;
276 e.y = oy;
277 }
278
279 @Override
280 public void mouseExit(MouseEvent e) {
281 int ox = e.x, oy = e.y;
282 e.x = viewToContentsX(e.x);
283 e.y = viewToContentsY(e.y);
284 contentsMouseExit(e);
285 e.x = ox;
286 e.y = oy;
287 }
288
289 };
290
eb63f5ff 291 fViewControl.addMouseTrackListener(localMouseTrackListener);
73005152 292
eb63f5ff 293 fLocalMouseListener = new MouseListener() {
73005152
BH
294 @Override
295 public void mouseDoubleClick(MouseEvent e) {
296 int ox = e.x, oy = e.y;
297 e.x = viewToContentsX(e.x);
298 e.y = viewToContentsY(e.y);
299 contentsMouseDoubleClickEvent(e);
300 e.x = ox;
301 e.y = oy;
302 }
303
304 @Override
305 public void mouseDown(MouseEvent e) {
306 int ox = e.x, oy = e.y;
eb63f5ff
BH
307 e.x = fMouseDownX = viewToContentsX(e.x);
308 e.y = fMousDownY = viewToContentsY(e.y);
73005152
BH
309 contentsMouseDownEvent(e);
310 e.x = ox;
311 e.y = oy;
312 }
313
314 @Override
315 public void mouseUp(MouseEvent e) {
316 int ox = e.x, oy = e.y;
317 e.x = viewToContentsX(e.x);
318 e.y = viewToContentsY(e.y);
319 contentsMouseUpEvent(e);
320 e.x = ox;
321 e.y = oy;
322 // here because class extenting me can catch mouse Up and want to scroll...
eb63f5ff 323 fMouseDownX = fMousDownY = -1;
73005152
BH
324 }
325 };
eb63f5ff 326 fViewControl.addMouseListener(fLocalMouseListener);
73005152 327
eb63f5ff 328 fLocalKeyListener = new KeyListener() {
73005152
BH
329 @Override
330 public void keyPressed(KeyEvent e) {
331 keyPressedEvent(e);
332 }
333
334 @Override
335 public void keyReleased(KeyEvent e) {
336 keyReleasedEvent(e);
337 }
338 };
df0b8ff4 339
eb63f5ff 340 fViewControl.addKeyListener(fLocalKeyListener);
73005152
BH
341
342 getVerticalBar().addSelectionListener(new SelectionListener() {
343 @Override
344 public void widgetSelected(SelectionEvent e) {
eb63f5ff 345 setContentsPos(fContentsX, getVerticalBar().getSelection());
73005152 346 // need to change "hidden" vertical bar value ?
eb63f5ff
BH
347 // force focus on fViewControl so we got future mouse wheel's scroll events
348 if (!fViewControl.isFocusControl()) {
349 fViewControl.setFocus();
df0b8ff4 350 }
73005152
BH
351 }
352
353 @Override
354 public void widgetDefaultSelected(SelectionEvent e) {
355 }
356 });
357
a55887ca 358 if (fViewControl.getVerticalBar() != null) {
eb63f5ff
BH
359 // add fViewControl hidden scrollbar listener to get mouse wheel ...
360 fViewControl.getVerticalBar().addSelectionListener(new SelectionListener() {
73005152
BH
361 @Override
362 public void widgetSelected(SelectionEvent e) {
eb63f5ff
BH
363 ScrollBar b = fViewControl.getVerticalBar();
364 setContentsPos(fContentsX, b.getSelection());
73005152
BH
365 // change "real" vertical bar selection too
366 getVerticalBar().setSelection(b.getSelection());
367 }
368
369 @Override
370 public void widgetDefaultSelected(SelectionEvent e) {
371 }
372 });
a55887ca 373 }
73005152
BH
374 getHorizontalBar().addSelectionListener(new SelectionListener() {
375 @Override
376 public void widgetSelected(SelectionEvent e) {
eb63f5ff 377 setContentsPos(getHorizontalBar().getSelection(), fContentsY);
73005152 378 // need to change "real" horizontal bar too ?
eb63f5ff
BH
379 // force focus on fViewControl so we got future mouse wheel's scroll events
380 if (!fViewControl.isFocusControl()) {
381 fViewControl.setFocus();
df0b8ff4 382 }
73005152
BH
383 }
384
385 @Override
386 public void widgetDefaultSelected(SelectionEvent e) {
387 }
388 });
a55887ca 389 if (fViewControl.getHorizontalBar() != null) {
eb63f5ff 390 fViewControl.getHorizontalBar().addSelectionListener(new SelectionListener() {
73005152
BH
391 @Override
392 public void widgetSelected(SelectionEvent e) {
eb63f5ff
BH
393 ScrollBar b = fViewControl.getHorizontalBar();
394 setContentsPos(b.getSelection(), fContentsY);
73005152
BH
395 // change "real" vertical bar selection too
396 getHorizontalBar().setSelection(b.getSelection());
397 }
398
399 @Override
400 public void widgetDefaultSelected(SelectionEvent e) {
401 }
402 });
a55887ca 403 }
73005152
BH
404 }
405
df0b8ff4
BH
406 // ------------------------------------------------------------------------
407 // Methods
408 // ------------------------------------------------------------------------
409
73005152
BH
410 @Override
411 public boolean setFocus() {
eb63f5ff 412 return fViewControl.forceFocus();
73005152
BH
413 }
414
415 @Override
416 public void setCursor(Cursor cursor) {
eb63f5ff 417 fViewControl.setCursor(cursor);
73005152
BH
418 }
419
73005152
BH
420 @Override
421 public void dispose() {
eb63f5ff
BH
422 if (fAutoScroll != null) {
423 fAutoScroll.cancel();
424 fAutoScroll = null;
73005152 425 }
eb63f5ff
BH
426 if (fViewControl != null) {
427 fViewControl.dispose();
df0b8ff4 428 }
eb63f5ff
BH
429 fViewControl = null;
430 if (fVertScrollBar != null) {
431 fVertScrollBar.dispose();
df0b8ff4 432 }
eb63f5ff
BH
433 fVertScrollBar = null;
434 if (fHorScrollBar != null) {
435 fHorScrollBar.dispose();
df0b8ff4 436 }
eb63f5ff
BH
437 fHorScrollBar = null;
438 if (fCornerControl != null) {
439 Object data = fCornerControl.getData();
73005152
BH
440 if (data instanceof Overview) {
441 ((Overview) data).dispose();
442 }
eb63f5ff
BH
443 fCornerControl.dispose();
444 fCornerControl = null;
73005152
BH
445 }
446 super.dispose();
447 }
448
73005152
BH
449 @Override
450 public Rectangle getClientArea() {
eb63f5ff 451 return fViewControl.getClientArea();
73005152
BH
452 }
453
73005152
BH
454 @Override
455 public void setBackground(Color c) {
456 super.setBackground(c);
eb63f5ff 457 fViewControl.setBackground(c);
73005152
BH
458 }
459
460 @Override
461 public void setToolTipText(String text) {
eb63f5ff 462 fViewControl.setToolTipText(text);
73005152
BH
463 }
464
465 /**
466 * Draw overview area, @see setOverviewEnabled. By default draw a rectangle corresponding to the visible area of
467 * scroll view. You can redefine this method to draw the contents as drawContents does... ...in an other magnify
468 * factor.
a55887ca 469 *
73005152
BH
470 * @param gc GC to used to draw.
471 * @param r Rectangle corresponding to the client area of overview.
472 */
473 protected void drawOverview(GC gc, Rectangle r) {
eb63f5ff
BH
474 int x = (int) (r.width * fContentsX / (float) fContentsWidth);
475 int y = (int) (r.height * fContentsY / (float) fContentsHeight);
73005152
BH
476 int vw = getVisibleWidth();
477 int vh = getVisibleHeight();
478 int w = r.width - 1;
eb63f5ff
BH
479 if (fContentsWidth > vw) {
480 w = (int) (r.width * vw / (float) fContentsWidth);
df0b8ff4 481 }
73005152 482 int h = r.height - 1;
eb63f5ff
BH
483 if (fContentsHeight > vh) {
484 h = (int) (r.height * vh / (float) fContentsHeight);
df0b8ff4 485 }
73005152
BH
486
487 gc.setForeground(getForeground());
488 // too small rectangle ?
489 if (w < 5 || h < 5) {
490 // use a cross ...
491 gc.drawLine(x, 0, x, r.height);
492 gc.drawLine(0, y, r.width, y);
493 } else {
494 gc.drawRectangle(x, y, w, h);
495 }
496 }
497
498 /**
499 * Remove the local Listener and add the new listener.
a55887ca 500 *
73005152
BH
501 * @param nlistener the new listener
502 */
503 public void replaceControlListener(ControlListener nlistener) {
eb63f5ff
BH
504 if (fLocalControlListener != null) {
505 removeControlListener(fLocalControlListener);
506 fLocalControlListener = null;
73005152
BH
507 }
508 addControlListener(nlistener);
509 }
510
511 /**
512 * Remove the local Listener and add the new listener.
a55887ca 513 *
73005152
BH
514 * @param nlistener the new listener
515 */
516 public void replaceKeyListener(KeyListener nlistener) {
eb63f5ff
BH
517 if (fLocalKeyListener != null) {
518 removeKeyListener(fLocalKeyListener);
519 fLocalKeyListener = null;
73005152
BH
520 }
521 addKeyListener(nlistener);
522 }
523
524 /**
525 * Remove the local Listener and add the new listener.
a55887ca 526 *
73005152
BH
527 * @param nlistener the new listener
528 */
529 public void replaceMouseListener(MouseListener nlistener) {
eb63f5ff
BH
530 if (fLocalMouseListener != null) {
531 removeMouseListener(fLocalMouseListener);
532 fLocalMouseListener = null;
73005152 533 }
eb63f5ff 534 fViewControl.addMouseListener(nlistener);
73005152
BH
535 }
536
537 /**
538 * Remove the local Listener and add the new listener.
a55887ca 539 *
73005152
BH
540 * @param nlistener the new listener
541 */
542 public void replaceMouseMoveListener(MouseMoveListener nlistener) {
eb63f5ff
BH
543 if (fLocalMouseMoveListener != null) {
544 removeMouseMoveListener(fLocalMouseMoveListener);
545 fLocalMouseMoveListener = null;
73005152 546 }
eb63f5ff 547 fViewControl.addMouseMoveListener(nlistener);
73005152
BH
548 }
549
550 /**
551 * Remove the local Listener and add the new listener.
a55887ca 552 *
73005152
BH
553 * @param nlistener the new listener
554 */
555 public void replacePaintListener(PaintListener nlistener) {
eb63f5ff
BH
556 if (fLocalPaintListener != null) {
557 removePaintListener(fLocalPaintListener);
558 fLocalPaintListener = null;
73005152 559 }
eb63f5ff 560 fViewControl.addPaintListener(nlistener);
73005152
BH
561 }
562
563 /**
564 * Access method for the contentsHeight property.
a55887ca 565 *
73005152
BH
566 * @return the current value of the contentsHeight property
567 */
568 public int getContentsHeight() {
eb63f5ff 569 return fContentsHeight;
73005152
BH
570 }
571
572 /**
573 * Access method for the contentsWidth property.
a55887ca 574 *
73005152
BH
575 * @return the current value of the contentsWidth property
576 */
577 public int getContentsWidth() {
eb63f5ff 578 return fContentsWidth;
73005152
BH
579 }
580
581 /**
582 * Access method for the contentsX property.
a55887ca 583 *
73005152
BH
584 * @return the current value of the contentsX property
585 */
586 public int getContentsX() {
eb63f5ff 587 return fContentsX;
73005152
BH
588 }
589
590 /**
591 * Access method for the contentsY property.
a55887ca 592 *
73005152
BH
593 * @return the current value of the contentsY property
594 */
595 public int getContentsY() {
eb63f5ff 596 return fContentsY;
73005152
BH
597 }
598
599 /**
600 * Determines if the dragAutoScroll property is true.
a55887ca 601 *
73005152
BH
602 * @return <code>true<code> if the dragAutoScroll property is true
603 */
3145ec83 604 public boolean isDragAutoScroll() {
eb63f5ff 605 return fAutoScrollEnabled;
73005152
BH
606 }
607
608 /**
609 * Sets the value of the dragAutoScroll property.
a55887ca 610 *
73005152
BH
611 * @param aDragAutoScroll the new value of the dragAutoScroll property
612 */
613 public void setDragAutoScroll(boolean aDragAutoScroll) {
eb63f5ff
BH
614 fAutoScrollEnabled = aDragAutoScroll;
615 if (!fAutoScrollEnabled && (fAutoScroll != null)) {
616 fAutoScroll.cancel();
617 fAutoScroll = null;
73005152
BH
618 }
619 }
620
621 /**
622 * Change delay (in millisec) used for auto scroll feature.
a55887ca 623 *
eb63f5ff 624 * @param period new period between to auto scroll
73005152 625 */
eb63f5ff
BH
626 public void setDragAutoScrollPeriod(int period) {
627 fAutoScrollPeriod = Math.max(0, period);
73005152
BH
628 }
629
630 /**
631 * Return auto scroll period.
a55887ca
AM
632 *
633 * @return The period
73005152
BH
634 */
635 public int getDragAutoScrollPeriod() {
eb63f5ff 636 return fAutoScrollPeriod;
73005152
BH
637 }
638
639 /**
640 * Access method for the hScrollBarMode property.
a55887ca 641 *
73005152
BH
642 * @return the current value of the hScrollBarMode property
643 */
644 public int getHScrollBarMode() {
eb63f5ff 645 return fHorScrollbarMode;
73005152
BH
646 }
647
648 /**
649 * Sets the value of the hScrollBarMode property.
a55887ca 650 *
73005152
BH
651 * @param aHScrollBarMode the new value of the hScrollBarMode property
652 */
653 public void setHScrollBarMode(int aHScrollBarMode) {
eb63f5ff 654 fHorScrollbarMode = aHScrollBarMode;
73005152
BH
655 }
656
657 /**
658 * Access method for the vScrollBarMode property.
a55887ca 659 *
73005152
BH
660 * @return the current value of the vScrollBarMode property
661 */
662 public int getVScrollBarMode() {
eb63f5ff 663 return fVertScrollbarMode;
73005152
BH
664 }
665
666 /**
667 * Sets the value of the vScrollBarMode property.
a55887ca 668 *
73005152
BH
669 * @param aVScrollBarMode the new value of the vScrollBarMode property
670 */
671 public void setVScrollBarMode(int aVScrollBarMode) {
eb63f5ff 672 fVertScrollbarMode = aVScrollBarMode;
73005152
BH
673 }
674
675 /**
676 * Return horizontal scroll bar increment, default:1
a55887ca
AM
677 *
678 * @return The increment
73005152
BH
679 */
680 public int getHScrollBarIncrement() {
eb63f5ff 681 return fHorScrollbarIncrement;
73005152
BH
682 }
683
684 /**
685 * Return vertical scroll bar increment, default:1
a55887ca
AM
686 *
687 * @return The increment
73005152
BH
688 */
689 public int getVScrollBarIncrement() {
eb63f5ff 690 return fVertScrollbarIncrement;
73005152
BH
691 }
692
693 /**
a55887ca
AM
694 * Change horizontal scroll bar increment, minimum:1. Page increment is
695 * always set to visible width.
696 *
697 * @param inc
698 * Increment value to set
73005152 699 */
eb63f5ff
BH
700 public void setHScrollBarIncrement(int inc) {
701 fHorScrollbarIncrement = Math.max(1, inc);
73005152
BH
702 }
703
704 /**
a55887ca
AM
705 * Change vertical scroll bar increment, minimum:1. Page increment is always
706 * set to visible height.
707 *
708 * @param inc
709 * Increment value to set
73005152 710 */
eb63f5ff
BH
711 public void setVScrollBarIncrement(int inc) {
712 fVertScrollbarIncrement = Math.max(1, inc);
73005152
BH
713 }
714
715 /**
716 * Enable or disable overview feature. Enabling overview, dispose and replace existing corner control by a button.
717 * Clicking in it open overview, move mouse cursor holding button to move scroll view and release button to hide
718 * overview. Tip: hold control and/or shift key while moving mouse when overview is open made fine scroll.
a55887ca 719 *
eb63f5ff 720 * @param value true to engage overview feature
73005152 721 */
eb63f5ff 722 public void setOverviewEnabled(boolean value) {
3145ec83 723 if (isOverviewEnabled() == value) {
73005152 724 return;
df0b8ff4 725 }
73005152
BH
726
727 Control cc = null;
eb63f5ff 728 if (value) {
73005152
BH
729 Button b = new Button(this, SWT.NONE);
730 b.setText("+"); //$NON-NLS-1$
731 Overview ovr = new Overview();
732 ovr.useControl(b);
733 b.setData(ovr);
734 cc = b;
735 b.setToolTipText(SDMessages._78);
736 }
737 setCornerControl(cc);
738 }
739
740 /**
741 * Change overview size (at ratio 1:1), default is 100
a55887ca
AM
742 *
743 * @param size
744 * The new size
73005152 745 */
eb63f5ff
BH
746 public void setOverviewSize(int size) {
747 fOverviewSize = Math.abs(size);
73005152
BH
748 }
749
750 /**
df0b8ff4 751 * Returns whether the overview is enabled or not.
a55887ca 752 *
73005152
BH
753 * @return true is overview feature is enabled
754 */
3145ec83 755 public boolean isOverviewEnabled() {
eb63f5ff
BH
756 if (fCornerControl instanceof Button) {
757 Object data = ((Button) fCornerControl).getData();
73005152 758 // overview alreay
df0b8ff4 759 if (data instanceof Overview) {
73005152 760 return true;
df0b8ff4 761 }
73005152
BH
762 }
763 return false;
764 }
765
766 /**
df0b8ff4 767 * Returns the overview size at ratio 1:1.
a55887ca 768 *
73005152
BH
769 * @return current overview size at ratio 1:1
770 */
771 public int getOverviewSize() {
eb63f5ff 772 return fOverviewSize;
73005152
BH
773 }
774
775 /**
df0b8ff4
BH
776 * Returns control used to display view (might not be this object). Use this control to add/remove listener on the
777 * draw area.
a55887ca
AM
778 *
779 * @return control used to display view (might not be this object).
73005152
BH
780 */
781 public Control getViewControl() {
eb63f5ff 782 return fViewControl;
73005152
BH
783 }
784
785 /**
786 * Called when the mouse enter the ScrollView area
a55887ca 787 *
73005152 788 * @param e
a0a88f65 789 * Mouse event
73005152
BH
790 */
791 protected void contentsMouseExit(MouseEvent e) {
792 }
793
794 /**
a0a88f65
AM
795 * Called when the mouse enter the ScrollView area after and system defined
796 * time
a55887ca 797 *
73005152 798 * @param e
a0a88f65 799 * Mouse event
73005152
BH
800 */
801 protected void contentsMouseHover(MouseEvent e) {
802 }
803
804 /**
805 * Called when the mouse enter the ScrollView area
a55887ca 806 *
73005152 807 * @param e
a0a88f65 808 * Mouse event
73005152
BH
809 */
810 protected void contentsMouseEnter(MouseEvent e) {
811 }
812
813 /**
814 * Called when user double on contents area.
a55887ca 815 *
73005152 816 * @param e
a0a88f65 817 * Mouse event
73005152
BH
818 */
819 protected void contentsMouseDoubleClickEvent(MouseEvent e) {
820 }
821
822 /**
823 * Called when mouse is on contents area and button is pressed.
a55887ca 824 *
73005152 825 * @param e
a0a88f65 826 * Mouse event
73005152
BH
827 */
828 protected void contentsMouseDownEvent(MouseEvent e) {
eb63f5ff
BH
829 fMouseDownX = e.x;
830 fMousDownY = e.y;
73005152
BH
831 }
832
a55887ca
AM
833 /**
834 * TimerTask for auto scroll feature.
eb63f5ff 835 */
73005152 836 protected static class AutoScroll extends TimerTask {
a0a88f65
AM
837
838 /** X delta */
eb63f5ff 839 public int deltaX;
a0a88f65
AM
840
841 /** Y delta */
eb63f5ff 842 public int deltaY;
a0a88f65
AM
843
844 /** ScrollView object */
eb63f5ff 845 public ScrollView scrollView;
73005152 846
a0a88f65
AM
847 /**
848 * Constructor.
849 *
850 * @param sv
851 * ScrollView object to use
852 * @param dx
853 * X delta
854 * @param dy
855 * Y delta
856 */
eb63f5ff
BH
857 public AutoScroll(ScrollView sv, int dx, int dy) {
858 scrollView = sv;
859 deltaX = dx;
860 deltaY = dy;
73005152
BH
861 }
862
863 @Override
864 public void run() {
865 Display.getDefault().asyncExec(new Runnable() {
866 @Override
867 public void run() {
eb63f5ff 868 scrollView.scrollBy(deltaX, deltaY);
73005152
BH
869 }
870 });
871 }
872 }
873
73005152
BH
874 /**
875 * Called when mouse is on contents area and mode.
a55887ca 876 *
eb63f5ff 877 * @param event
a0a88f65 878 * Mouse event
73005152 879 */
eb63f5ff
BH
880 protected void contentsMouseMoveEvent(MouseEvent event) {
881 if ((event.stateMask & SWT.BUTTON_MASK) != 0) {
882 if (!fAutoScrollEnabled) {
883 scrollBy(-(event.x - fMouseDownX), -(event.y - fMousDownY));
73005152
BH
884 return;
885 }
886
887 int sx = 0, sy = 0;
888
889 int v_right = getContentsX() + getVisibleWidth();
890 int v_bottom = getContentsY() + getVisibleHeight();
891
892 // auto scroll... ?
eb63f5ff
BH
893 if (event.x < getContentsX()) {
894 sx = (getContentsX() - event.x);
895 fMouseDownX = getContentsX();
896 } else if (event.x > v_right) {
897 sx = -event.x + v_right;
898 fMouseDownX = v_right;
73005152 899 }
eb63f5ff
BH
900 if (event.y < getContentsY()) {
901 sy = (getContentsY() - event.y);
902 fMousDownY = getContentsY();
903 } else if (event.y > v_bottom) {
904 sy = -event.y + v_bottom;
905 fMousDownY = v_bottom;
73005152
BH
906 }
907
908 if (sx != 0 || sy != 0) {
909 // start auto scroll...
eb63f5ff
BH
910 if (fAutoScroll == null) {
911 if (fAutoScrollTimer == null) {
912 fAutoScrollTimer = new Timer(true);
73005152 913 }
eb63f5ff
BH
914 fAutoScroll = new AutoScroll(this, sx, sy);
915 fAutoScrollTimer.schedule(fAutoScroll, 0, fAutoScrollPeriod);
73005152 916 } else {
eb63f5ff
BH
917 fAutoScroll.deltaX = sx;
918 fAutoScroll.deltaY = sy;
73005152
BH
919 }
920 } else {
eb63f5ff
BH
921 if (fAutoScroll != null) {
922 fAutoScroll.cancel();
923 fAutoScroll = null;
73005152
BH
924 }
925
eb63f5ff 926 scrollBy(-(event.x - fMouseDownX), -(event.y - fMousDownY));
73005152
BH
927 }
928 }
929 }
930
931 /**
932 * Called when mouse is on contents area and button is released
a55887ca 933 *
eb63f5ff 934 * @param event
a0a88f65 935 * Mouse event
73005152 936 */
eb63f5ff 937 protected void contentsMouseUpEvent(MouseEvent event) {
73005152 938 // reset auto scroll if it's engaged
eb63f5ff
BH
939 if (fAutoScroll != null) {
940 fAutoScroll.cancel();
941 fAutoScroll = null;
73005152
BH
942 }
943 }
944
945 /**
a0a88f65
AM
946 * Responsible to draw contents area. At least rectangle clipX must be
947 * redrawn. This rectangle is given in contents coordinates. By default, no
948 * paint is produced.
a55887ca 949 *
73005152 950 * @param gc
a0a88f65 951 * Graphics context
73005152 952 * @param clipx
a0a88f65 953 * X clip
73005152 954 * @param clipy
a0a88f65 955 * Y clip
73005152 956 * @param clipw
a0a88f65 957 * W clip
73005152 958 * @param cliph
a0a88f65 959 * H clip
73005152
BH
960 */
961 protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) {
962 }
963
964 /**
965 * Change the size of the contents area.
a55887ca 966 *
0d9a6d76
FC
967 * @param width new width of the area.
968 * @param height new height of the area.
73005152 969 */
0d9a6d76 970 public void resizeContents(int width, int height) {
eb63f5ff
BH
971 int localWidth = width;
972 int localHeight = height;
a55887ca 973
eb63f5ff
BH
974 if (localWidth < 0) {
975 localWidth = 0;
df0b8ff4 976 }
eb63f5ff
BH
977 if (localHeight < 0) {
978 localHeight = 0;
df0b8ff4 979 }
73005152 980
eb63f5ff
BH
981 int oldW = fContentsWidth;
982 int oldH = fContentsHeight;
73005152 983
eb63f5ff 984 if (localWidth == oldW && localHeight == oldH) {
73005152 985 return;
df0b8ff4 986 }
73005152 987
eb63f5ff
BH
988 fContentsWidth = localWidth;
989 fContentsHeight = localHeight;
73005152 990
eb63f5ff
BH
991 if (oldW > localWidth) {
992 int s = localWidth;
993 localWidth = oldW;
73005152
BH
994 oldW = s;
995 }
996
997 int vis_width = getVisibleWidth();
998 int vis_height = getVisibleHeight();
999 if (oldW < vis_width) {
eb63f5ff
BH
1000 if (localWidth > vis_width) {
1001 localWidth = vis_width;
73005152 1002 }
eb63f5ff 1003 fViewControl.redraw(getContentsX() + oldW, 0, localWidth - oldW, vis_height, true);
73005152
BH
1004 }
1005
eb63f5ff
BH
1006 if (oldH > localHeight) {
1007 int s = localHeight;
1008 localHeight = oldH;
73005152
BH
1009 oldH = s;
1010 }
1011
1012 if (oldH < vis_height) {
eb63f5ff
BH
1013 if (localHeight > vis_height) {
1014 localHeight = vis_height;
73005152 1015 }
eb63f5ff 1016 fViewControl.redraw(0, getContentsY() + oldH, vis_width, localHeight - oldH, true);
73005152
BH
1017 }
1018 if (updateScrollBarVisiblity()) {
1019 layout();
1020 } else {
1021 updateScrollBarsValues();
1022 }
73005152
BH
1023 }
1024
1025 // redefined for internal use ..
1026 @Override
1027 public void redraw() {
1028 super.redraw();
1029 // ..need to redraw this already:
eb63f5ff 1030 fViewControl.redraw();
73005152
BH
1031 }
1032
1033 /**
a55887ca 1034 * @param delataX The delta in X
eb63f5ff 1035 * @param deltaY the delta in Y
73005152 1036 */
eb63f5ff
BH
1037 public void scrollBy(int delataX, int deltaY) {
1038 setContentsPos(getContentsX() + delataX, getContentsY() + deltaY);
73005152
BH
1039 }
1040
1041 /**
1042 * Scroll to ensure point(in contents coordinates) is visible.
a55887ca 1043 *
eb63f5ff
BH
1044 * @param px Point's x position
1045 * @param py Point's y position
73005152 1046 */
eb63f5ff 1047 public void ensureVisible(int px, int py) {
73005152
BH
1048 int cx = getContentsX(), cy = getContentsY();
1049 int right = getContentsX() + getVisibleWidth();
1050 int bottom = getContentsY() + getVisibleHeight();
eb63f5ff
BH
1051 if (px < getContentsX()) {
1052 cx = px;
1053 } else if (px > right) {
1054 cx = px - getVisibleWidth();
73005152 1055 }
eb63f5ff
BH
1056 if (py < getContentsY()) {
1057 cy = py;
1058 } else if (py > bottom) {
1059 cy = py - getVisibleHeight();
73005152
BH
1060 }
1061 setContentsPos(cx, cy);
1062 }
1063
1064 /**
eb63f5ff
BH
1065 * Make rectangle (x,y,w,h, in contents coordinates) visible. if rectangle cannot be completely visible, use
1066 * align flags.
a55887ca 1067 *
eb63f5ff
BH
1068 * @param xValue x contents coordinates of rectangle.
1069 * @param yValue y contents coordinates of rectangle.
1070 * @param width width of rectangle.
1071 * @param height height of rectangle.
1072 * @param align bit or'ed SWT flag like SWT.LEFT,RIGHT,CENTER,TOP,BOTTOM,VERTICAL used only for bigger rectangle
73005152
BH
1073 * than visible area. By default CENTER/VERTICAL
1074 */
eb63f5ff
BH
1075 public void ensureVisible(int xValue, int yValue, int width, int height, int align) {
1076 ensureVisible(xValue, yValue, width, height, align, false);
73005152
BH
1077 }
1078
1079 /**
eb63f5ff
BH
1080 * Make rectangle (xValue,yValue,width,height, in contents coordinates) visible. if rectangle cannot be completely visible, use
1081 * align flags.
a55887ca 1082 *
eb63f5ff
BH
1083 * @param xValue x contents coordinates of rectangle.
1084 * @param yValue y contents coordinates of rectangle.
1085 * @param width width of rectangle.
1086 * @param height height of rectangle.
1087 * @param align bit or'ed SWT flag like SWT.LEFT,RIGHT,CENTER,TOP,BOTTOM,VERTICAL used only for bigger rectangle
73005152
BH
1088 * than visible area. By default CENTER/VERTICAL
1089 * @param forceAlign force alignment for rectangle smaller than the visible area
1090 */
eb63f5ff 1091 protected void ensureVisible(int xValue, int yValue, int width, int height, int align, boolean forceAlign) {
a55887ca 1092
3145ec83
BH
1093 int localX = xValue;
1094 int localY = yValue;
eb63f5ff
BH
1095 int localWidth = width;
1096 int localHeight = height;
1097
1098 if (localWidth < 0) {
3145ec83 1099 localX = localX + localWidth;
eb63f5ff 1100 localWidth = -localWidth;
73005152 1101 }
eb63f5ff 1102 if (localHeight < 0) {
3145ec83 1103 localY = localY + localHeight;
eb63f5ff 1104 localHeight = -localHeight;
73005152
BH
1105 }
1106 int hbar = getHorizontalBarHeight();
1107 int vbar = getVerticalBarWidth();
3145ec83
BH
1108 int cx = getContentsX();
1109 int cy = getContentsY();
73005152
BH
1110 int right = getContentsX() + getVisibleWidth() - vbar;
1111 int bottom = getContentsY() + getVisibleHeight() - hbar;
1112 boolean align_h = false, align_v = false;
1113
3145ec83
BH
1114 if (localX < getContentsX()) {
1115 cx = localX;
1116 } else if (localX + localWidth > right) {
1117 cx = localX - localWidth;
73005152 1118 }
3145ec83
BH
1119 if (localY < getContentsY()) {
1120 cy = localY;
1121 } else if (localY + localHeight > bottom) {
1122 cy = localY - localHeight;
73005152
BH
1123 }
1124
eb63f5ff 1125 if (localWidth > getVisibleWidth()) {
73005152 1126 align_h = true;
df0b8ff4 1127 }
eb63f5ff 1128 if (localHeight > getVisibleHeight()) {
73005152 1129 align_v = true;
df0b8ff4 1130 }
73005152 1131 // compute alignment on visible area horizontally
3145ec83 1132 if (align_h || (forceAlign && localX + localWidth > right)) {
eb63f5ff
BH
1133 // use align flags
1134 if ((align & SWT.LEFT) != 0) {
3145ec83 1135 cx = localX;
eb63f5ff
BH
1136 } else if ((align & SWT.RIGHT) != 0) {
1137 cx = right - localWidth;
df0b8ff4 1138 } else { // center
3145ec83 1139 cx = localX + (localWidth - getVisibleWidth()) / 2;
73005152
BH
1140 }
1141 }
1142 // compute alignment on visible area vertically
3145ec83 1143 if (align_v || (forceAlign && localY + localHeight > bottom)) {
eb63f5ff
BH
1144 // use align flags
1145 if ((align & SWT.TOP) != 0) {
3145ec83 1146 cy = localY;
eb63f5ff
BH
1147 } else if ((align & SWT.BOTTOM) != 0) {
1148 cy = bottom - localHeight;
df0b8ff4 1149 } else { // center
3145ec83 1150 cy = localY + (localHeight - getVisibleHeight()) / 2;
73005152
BH
1151 }
1152 }
1153 setContentsPos(cx, cy);
1154 }
1155
1156 /**
df0b8ff4 1157 * Returns true if point is visible (expressed in contents coordinates).
a55887ca 1158 *
eb63f5ff
BH
1159 * @param px Point's x position
1160 * @param py Point's y position
73005152
BH
1161 * @return true if point is visible (expressed in contents coordinates)
1162 */
eb63f5ff
BH
1163 public boolean isVisible(int px, int py) {
1164 if (px < getContentsX()) {
73005152 1165 return false;
df0b8ff4 1166 }
eb63f5ff 1167 if (py < getContentsY()) {
73005152 1168 return false;
df0b8ff4 1169 }
eb63f5ff 1170 if (px > (getContentsX() + getVisibleWidth())) {
73005152 1171 return false;
df0b8ff4 1172 }
eb63f5ff 1173 if (py > (getContentsY() + getVisibleHeight())) {
73005152 1174 return false;
df0b8ff4 1175 }
73005152
BH
1176 return true;
1177 }
1178
1179 /**
df0b8ff4 1180 * Returns true if rectangle if partially visible.
a55887ca 1181 *
eb63f5ff
BH
1182 * @param xValue x contents coordinates of rectangle.
1183 * @param yValue y contents coordinates of rectangle.
1184 * @param width width of rectangle.
1185 * @param height height of rectangle.
73005152
BH
1186 * @return true if rectangle if partially visible.
1187 */
eb63f5ff
BH
1188 public boolean isVisible(int xValue, int yValue, int width, int height) {
1189 if (xValue + width < getContentsX()) {
73005152 1190 return false;
df0b8ff4 1191 }
eb63f5ff 1192 if (yValue + height < getContentsY()) {
73005152 1193 return false;
df0b8ff4 1194 }
73005152
BH
1195 int vr = getContentsX() + getVisibleWidth();
1196 int vb = getContentsY() + getVisibleHeight();
eb63f5ff 1197 if (xValue > vr) {
73005152 1198 return false;
df0b8ff4 1199 }
eb63f5ff 1200 if (yValue > vb) {
73005152 1201 return false;
df0b8ff4 1202 }
73005152
BH
1203 return true;
1204 }
1205
1206 /**
a55887ca
AM
1207 * Returns visible part of rectangle, or null if rectangle is not visible.
1208 * Rectangle is expressed in contents coordinates.
eb63f5ff 1209 *
a55887ca
AM
1210 * @param xValue
1211 * x contents coordinates of rectangle.
1212 * @param yValue
1213 * y contents coordinates of rectangle.
1214 * @param width
1215 * width of rectangle.
1216 * @param height
1217 * height of rectangle.
1218 * @return visible part of rectangle, or null if rectangle is not visible.
1219 */
1220 public Rectangle getVisiblePart(int xValue, int yValue, int width, int height) {
eb63f5ff 1221 if (xValue + width < getContentsX()) {
73005152 1222 return null;
df0b8ff4 1223 }
a55887ca 1224 if (yValue + height < getContentsY()) {
73005152 1225 return null;
df0b8ff4 1226 }
73005152
BH
1227 int vr = getContentsX() + getVisibleWidth();
1228 int vb = getContentsY() + getVisibleHeight();
eb63f5ff 1229 if (xValue > vr) {
73005152 1230 return null;
df0b8ff4 1231 }
a55887ca 1232 if (yValue > vb) {
73005152 1233 return null;
df0b8ff4 1234 }
a55887ca
AM
1235 int rr = xValue + width, rb = yValue + height;
1236 int nl = Math.max(xValue, getContentsX()), nt = Math.max(yValue, getContentsY()), nr = Math.min(rr, vr), nb = Math.min(rb, vb);
eb63f5ff 1237 return new Rectangle(nl, nt, nr - nl, nb - nt);
73005152
BH
1238 }
1239
df0b8ff4 1240 /**
a55887ca
AM
1241 * Returns the visible part for given rectangle.
1242 *
eb63f5ff 1243 * @param rect A rectangle
a55887ca 1244 *
df0b8ff4
BH
1245 * @return gets visible part of rectangle (or <code>null</code>)
1246 */
eb63f5ff
BH
1247 public final Rectangle getVisiblePart(Rectangle rect) {
1248 if (rect == null) {
73005152 1249 return null;
df0b8ff4 1250 }
eb63f5ff 1251 return getVisiblePart(rect.x, rect.y, rect.width, rect.height);
73005152
BH
1252 }
1253
1254 /**
1255 * Change top left position of visible area. Check if the given point is inside contents area.
a55887ca 1256 *
eb63f5ff
BH
1257 * @param xValue x contents coordinates of visible area.
1258 * @param yValue y contents coordinates of visible area.
73005152
BH
1259 * @return true if view really moves
1260 */
eb63f5ff
BH
1261 public boolean setContentsPos(int xValue, int yValue) {
1262 int nx = xValue, ny = yValue;
73005152
BH
1263 if (getVisibleWidth() >= getContentsWidth()) {
1264 nx = 0;
1265 } else {
eb63f5ff 1266 if (xValue < 0) {
73005152 1267 nx = 0;
eb63f5ff 1268 } else if (xValue + getVisibleWidth() > getContentsWidth()) {
73005152
BH
1269 nx = getContentsWidth() - getVisibleWidth();
1270 }
1271 }
1272 if (getVisibleHeight() >= getContentsHeight()) {
1273 ny = 0;
1274 } else {
eb63f5ff 1275 if (yValue <= 0) {
73005152 1276 ny = 0;
eb63f5ff 1277 } else if (yValue + getVisibleHeight() > getContentsHeight()) {
73005152
BH
1278 ny = getContentsHeight() - getVisibleHeight();
1279 }
1280 }
1281 // no move
eb63f5ff 1282 if (nx == fContentsX && ny == fContentsY) {
73005152
BH
1283 return false;
1284 }
eb63f5ff
BH
1285 fContentsX = nx;
1286 fContentsY = ny;
73005152
BH
1287 updateScrollBarsValues();
1288 // ? find smallest area to redraw only them ?
eb63f5ff 1289 fViewControl.redraw();
73005152
BH
1290 return true;
1291 }
1292
73005152
BH
1293 @Override
1294 public ScrollBar getVerticalBar() {
eb63f5ff 1295 return fVertScrollBar.getVerticalBar();
73005152
BH
1296 }
1297
73005152
BH
1298 @Override
1299 public ScrollBar getHorizontalBar() {
eb63f5ff 1300 return fHorScrollBar.getHorizontalBar();
73005152
BH
1301 }
1302
73005152 1303 /**
df0b8ff4 1304 * Compute visibility of vertical/horizontal bar using given width/height and current visibility (i.e. is bar size are already in
73005152 1305 * for_xxx)
eb63f5ff
BH
1306 * @param forWidth width of foreground
1307 * @param forHeight height of foreground
1308 * @param currHorVis The current visibility state of horizontal scroll bar
1309 * @param currVertvis The current visibility state of vertical scroll bar
a55887ca 1310 * @return <code>true</code> if visibility changed else <code>false</code>
73005152 1311 */
eb63f5ff 1312 public int computeBarVisibility(int forWidth, int forHeight, boolean currHorVis, boolean currVertvis) {
a55887ca 1313
eb63f5ff 1314 int localForWidth = forWidth;
73005152 1315 int vis = 0x00;
eb63f5ff 1316 switch (fVertScrollbarMode) {
73005152
BH
1317 case ALWAYS_OFF:
1318 break;
1319 case ALWAYS_ON:
1320 vis |= VBAR;
1321 break;
1322 case AUTO:
eb63f5ff 1323 if (getContentsHeight() > forHeight) {
73005152
BH
1324 vis = VBAR;
1325 // v bar size is already in for_width.
eb63f5ff
BH
1326 if (!currVertvis) {// (curr_vis&0x01)==0)
1327 localForWidth -= getVerticalBarWidth();
73005152
BH
1328 }
1329 }
1330 break;
3145ec83
BH
1331 default:
1332 break;
73005152 1333 }
df0b8ff4 1334
eb63f5ff 1335 switch (fHorScrollbarMode) {
73005152
BH
1336 case ALWAYS_OFF:
1337 break;
1338 case ALWAYS_ON:
1339 vis |= HBAR;
1340 break;
1341 case AUTO:
eb63f5ff 1342 if (getContentsWidth() > localForWidth) {
73005152
BH
1343 vis |= HBAR;
1344 // h bar is not in for_height
eb63f5ff
BH
1345 if ((!currHorVis) && (getContentsHeight() > (forHeight - getHorizontalBarHeight()))) {// (curr_vis&0x02)==0 )
1346 vis |= VBAR;
73005152
BH
1347 }
1348 }
1349 break;
3145ec83
BH
1350 default:
1351 break;
73005152
BH
1352 }
1353 return vis;
1354 }
1355
1356 /**
a0a88f65
AM
1357 * Setup scroll bars visibility.
1358 *
1359 * @return True if one of visibility changed.
73005152
BH
1360 */
1361 protected boolean updateScrollBarVisiblity() {
1362 boolean change = false;
1363
eb63f5ff
BH
1364 boolean currVertVis = fVertScrollBar.getVisible();
1365 boolean currHorVis = fHorScrollBar.getVisible();
1366 int barNewVis = computeBarVisibility(getVisibleWidth(), getVisibleHeight(), currHorVis, currVertVis);
1367 boolean newVertVis = (barNewVis & VBAR) != 0;
1368 boolean newHorVis = (barNewVis & HBAR) != 0;
eb63f5ff
BH
1369 if (currVertVis ^ newVertVis) { // vertsb_.getVisible() )
1370 fVertScrollBar.setVisible(newVertVis);
73005152
BH
1371 change = true;
1372 }
eb63f5ff
BH
1373 if (currHorVis ^ newHorVis) {
1374 fHorScrollBar.setVisible(newHorVis);
73005152
BH
1375 change = true;
1376 }
1377
1378 // update corner control visibility:
eb63f5ff
BH
1379 if (fCornerControl != null && change) {
1380 boolean vis = newVertVis || newHorVis;
1381 if (vis ^ fCornerControl.getVisible()) {
1382 fCornerControl.setVisible(vis);
73005152
BH
1383 change = true; // but must be already the case
1384 }
1385 }
1386 return change;
1387 }
1388
1389 /**
1390 * Setup scroll bar using contents, visible and scroll bar mode properties.
73005152
BH
1391 */
1392 protected void updateScrollBarsValues() {
73005152
BH
1393 /* update vertical scrollbar */
1394 ScrollBar b = getVerticalBar();
1395 if (b != null) {
1396 b.setMinimum(0);
1397 b.setMaximum(getContentsHeight());
1398 b.setThumb(getVisibleHeight());
1399 b.setPageIncrement(getVisibleHeight());
eb63f5ff 1400 b.setIncrement(fVertScrollbarIncrement);
73005152
BH
1401 b.setSelection(getContentsY());
1402 }
1403
1404 // update "hidden" vertical bar too
eb63f5ff 1405 b = fViewControl.getVerticalBar();
73005152
BH
1406 if (b != null) {
1407 b.setMinimum(0);
1408 b.setMaximum(getContentsHeight());
1409 b.setThumb(getVisibleHeight());
1410 b.setPageIncrement(getVisibleHeight());
eb63f5ff 1411 b.setIncrement(fVertScrollbarIncrement);
73005152
BH
1412 b.setSelection(getContentsY());
1413 }
1414
1415 /* update horizontal scrollbar */
1416 b = getHorizontalBar();
1417 if (b != null) {
1418 b.setMinimum(0);
1419 b.setMaximum(getContentsWidth());
1420 b.setThumb(getVisibleWidth());
1421 b.setSelection(getContentsX());
1422 b.setPageIncrement(getVisibleWidth());
eb63f5ff 1423 b.setIncrement(fHorScrollbarIncrement);
73005152
BH
1424 }
1425 // update "hidden" horizontal bar too
eb63f5ff 1426 b = fViewControl.getHorizontalBar();
73005152
BH
1427 if (b != null) {
1428 b.setMinimum(0);
1429 b.setMaximum(getContentsWidth());
1430 b.setThumb(getVisibleWidth());
1431 b.setSelection(getContentsX());
1432 b.setPageIncrement(getVisibleWidth());
eb63f5ff 1433 b.setIncrement(fHorScrollbarIncrement);
73005152
BH
1434 }
1435 }
1436
1437 /**
1438 * Change the control used in the bottom right corner (between two scrollbar), if control is null reset previous
1439 * corner control. This control is visible only if at least one scrollbar is visible. Given control will be disposed
1440 * by ScrollView, at dispose() time, at next setCornetControl() call or when calling setOverviewEnabled(). Pay
1441 * attention calling this reset overview feature until setOverviewEnabled(true) if called.
a55887ca 1442 * @param control The control for the overview
73005152 1443 */
eb63f5ff
BH
1444 public void setCornerControl(Control control) {
1445 if (fCornerControl != null) {
1446 fCornerControl.dispose();
73005152 1447 }
eb63f5ff
BH
1448 fCornerControl = control;
1449 if (fCornerControl != null) {
73005152
BH
1450 ScrollBar vb = getVerticalBar();
1451 ScrollBar hb = getHorizontalBar();
1452 boolean vis = vb.getVisible() || hb.getVisible();
eb63f5ff 1453 fCornerControl.setVisible(vis);
73005152
BH
1454 }
1455 }
1456
1457 /**
1458 * Transform (x,y) point in widget coordinates to contents coordinates.
a55887ca 1459 *
df0b8ff4
BH
1460 * @param x The x widget coordinate.
1461 * @param y The y widget coordinate.
1462 * @return org.eclipse.swt.graphics.Point with content coordinates.
73005152 1463 */
0d9a6d76 1464 public final Point viewToContents(int x, int y) {
eb63f5ff 1465 return new Point(viewToContentsX(x), viewToContentsY(y));
73005152
BH
1466 }
1467
a55887ca 1468 /**
df0b8ff4 1469 * Transform x in widget coordinates to contents coordinates
a55887ca 1470 *
eb63f5ff 1471 * @param x The y widget coordinate.
a55887ca 1472 * @return the x content coordinate.
df0b8ff4 1473 */
eb63f5ff
BH
1474 public int viewToContentsX(int x) {
1475 return fContentsX + x;
73005152
BH
1476 }
1477
a55887ca 1478 /**
df0b8ff4 1479 * Transform y in widget coordinates to contents coordinates
a55887ca 1480 *
eb63f5ff 1481 * @param y The y widget coordinate.
a55887ca 1482 * @return the y content coordinate.
df0b8ff4 1483 */
eb63f5ff
BH
1484 public int viewToContentsY(int y) {
1485 return fContentsY + y;
73005152
BH
1486 }
1487
1488 /**
1489 * Transform (x,y) point from contents coordinates, to widget coordinates.
a55887ca 1490 *
df0b8ff4
BH
1491 * @param x The x content coordinate.
1492 * @param y The y content coordinate.
1493 * @return coordinates widget area as.
73005152 1494 */
0d9a6d76 1495 public final Point contentsToView(int x, int y) {
eb63f5ff 1496 return new Point(contentsToViewX(x), contentsToViewY(y));
73005152
BH
1497 }
1498
1499 /**
1500 * Transform X axis coordinates from contents to widgets.
a55887ca 1501 *
eb63f5ff 1502 * @param x contents coordinate to transform.
df0b8ff4 1503 * @return x coordinate in widget area
73005152 1504 */
eb63f5ff
BH
1505 public int contentsToViewX(int x) {
1506 return x - fContentsX;
73005152
BH
1507 }
1508
1509 /**
1510 * Transform Y axis coordinates from contents to widgets.
a55887ca 1511 *
eb63f5ff 1512 * @param y contents coordinate to transform
df0b8ff4 1513 * @return y coordinate in widget area
73005152 1514 */
eb63f5ff
BH
1515 public int contentsToViewY(int y) {
1516 return y - fContentsY;
73005152
BH
1517 }
1518
1519 /**
df0b8ff4 1520 * Return the visible height of scroll view, might be > contentsHeight
a55887ca 1521 *
df0b8ff4 1522 * @return the visible height of scroll view, might be > contentsHeight()
73005152
BH
1523 */
1524 public int getVisibleHeight() {
3145ec83 1525 return fViewControl.getClientArea().height;
73005152
BH
1526 }
1527
1528 /**
df0b8ff4 1529 * Return int the visible width of scroll view, might be > contentsWidth().
a55887ca 1530 *
73005152
BH
1531 * @return int the visible width of scroll view, might be > contentsWidth()
1532 */
1533 public int getVisibleWidth() {
3145ec83 1534 return fViewControl.getClientArea().width;
73005152
BH
1535 }
1536
1537 /**
a0a88f65
AM
1538 * Add support for arrow key, scroll the ... scroll view. But you can
1539 * redefine this method for your convenience.
1540 *
1541 * @param event
1542 * Keyboard event
73005152 1543 */
eb63f5ff
BH
1544 protected void keyPressedEvent(KeyEvent event) {
1545 switch (event.keyCode) {
73005152
BH
1546 case SWT.ARROW_UP:
1547 scrollBy(0, -getVisibleHeight());
1548 break;
1549 case SWT.ARROW_DOWN:
1550 scrollBy(0, +getVisibleHeight());
1551 break;
1552 case SWT.ARROW_LEFT:
1553 scrollBy(-getVisibleWidth(), 0);
1554 break;
1555 case SWT.ARROW_RIGHT:
1556 scrollBy(+getVisibleWidth(), 0);
1557 break;
3145ec83
BH
1558 default:
1559 break;
73005152
BH
1560 }
1561 }
1562
a55887ca 1563 /**
df0b8ff4 1564 * Redefine this method at your convenience
a55887ca 1565 *
eb63f5ff 1566 * @param event The key event.
df0b8ff4 1567 */
eb63f5ff 1568 protected void keyReleasedEvent(KeyEvent event) {
73005152
BH
1569 }
1570
df0b8ff4
BH
1571 /**
1572 * Returns vertical bar width, even if bar isn't visible.
a55887ca
AM
1573 *
1574 * @return vertical bar width, even if bar isn't visible
df0b8ff4 1575 */
73005152
BH
1576 public int getVerticalBarWidth() {
1577 // include vertical bar width and trimming of scrollable used
eb63f5ff 1578 int bw = fVertScrollBar.computeTrim(0, 0, 0, 0).width;
73005152
BH
1579 return bw + 1;
1580 }
1581
df0b8ff4
BH
1582 /**
1583 * Returns horizontal bar height even if bar isn't visible.
a55887ca
AM
1584 *
1585 * @return horizontal bar height even if bar isn't visible
df0b8ff4 1586 */
73005152
BH
1587 public int getHorizontalBarHeight() {
1588 // include horiz. bar height and trimming of scrollable used
eb63f5ff 1589 int bh = fHorScrollBar.computeTrim(0, 0, 0, 0).height;
73005152
BH
1590 // +1 because win32 H.bar need 1 pixel canvas size to appear ! (strange no ?)
1591 return bh + 1;
1592 }
1593
1594 @Override
1595 public Rectangle computeTrim(int x, int y, int w, int h) {
1596 Rectangle r = new Rectangle(x, y, w, h);
1597 int bar_vis = computeBarVisibility(w, h, false, false);
1598 if ((bar_vis & VBAR) != 0) {
1599 r.width += getVerticalBarWidth();
1600 }
1601 if ((bar_vis & HBAR) != 0) {
1602 r.height += getHorizontalBarHeight();
1603 }
1604 return r;
1605 }
1606
df0b8ff4 1607 /**
a55887ca 1608 * Internal layout for ScrollView, handle scrollbars, drawzone and corner control
df0b8ff4 1609 */
73005152 1610 protected class SVLayout extends Layout {
eb63f5ff
BH
1611 /**
1612 * The seek value
1613 */
df0b8ff4 1614 int seek = 0;
eb63f5ff
BH
1615 /**
1616 * The do-it-not flag
1617 */
1618 boolean dontLayout = false;
a55887ca 1619
73005152
BH
1620 @Override
1621 protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
1622 Point p = new Point(250, 250);
eb63f5ff
BH
1623 if (fContentsWidth < p.x) {
1624 p.x = fContentsWidth;
df0b8ff4 1625 }
eb63f5ff
BH
1626 if (fContentsHeight < p.y) {
1627 p.y = fContentsHeight;
df0b8ff4 1628 }
73005152
BH
1629 return p;
1630 }
1631
73005152
BH
1632 @Override
1633 protected void layout(Composite composite, boolean flushCache) {
eb63f5ff 1634 if (dontLayout) {
73005152 1635 return;
df0b8ff4 1636 }
73005152 1637 seek++;
df0b8ff4 1638 if (seek > 10) {
eb63f5ff 1639 dontLayout = true;
df0b8ff4 1640 }
73005152 1641
73005152
BH
1642 Point cs = composite.getSize();
1643 int bar_vis = computeBarVisibility(cs.x, cs.y, false, false);
1644 boolean vb_vis = (bar_vis & VBAR) != 0;
1645 boolean hb_vis = (bar_vis & HBAR) != 0;
eb63f5ff
BH
1646 fVertScrollBar.setVisible(vb_vis);
1647 fHorScrollBar.setVisible(hb_vis);
73005152
BH
1648 int vbw = getVerticalBarWidth();
1649 int hbh = getHorizontalBarHeight();
1650 int wb = vb_vis ? vbw : 0;
1651 int hb = hb_vis ? hbh : 0;
1652 int cww = 0, cwh = 0;
73005152 1653
eb63f5ff
BH
1654 if (fCornerControl != null && (vb_vis || hb_vis)) { // corner_control_.getVisible())
1655 fCornerControl.setVisible(true);
73005152
BH
1656 cww = vbw;
1657 cwh = hbh;
a55887ca 1658 if (wb == 0) {
73005152 1659 wb = vbw;
a55887ca
AM
1660 }
1661 if (hb == 0) {
73005152 1662 hb = hbh;
a55887ca 1663 }
73005152 1664 } else if (vb_vis && hb_vis) {
eb63f5ff
BH
1665 if (fCornerControl != null) {
1666 fCornerControl.setVisible(false);
df0b8ff4 1667 }
73005152
BH
1668 cww = vbw;
1669 cwh = hbh;
1670 }
df0b8ff4 1671 if (vb_vis || hb_vis) {
73005152 1672 updateScrollBarsValues();
df0b8ff4 1673 }
73005152
BH
1674
1675 int vw = cs.x - (vb_vis ? vbw : 0);
1676 int vh = cs.y - (hb_vis ? hbh : 0);
1677 int vbx = cs.x - wb;
1678 int hby = cs.y - hb;
a55887ca 1679
eb63f5ff 1680 fViewControl.setBounds(0, 0, vw, vh);
3145ec83 1681
73005152 1682 if (vb_vis) {
eb63f5ff 1683 fVertScrollBar.setBounds(vbx, 0, wb, cs.y - cwh);
73005152
BH
1684 }
1685 if (hb_vis) {
eb63f5ff 1686 fHorScrollBar.setBounds(0, hby, cs.x - cww, hb);
73005152 1687 }
eb63f5ff
BH
1688 if (fCornerControl != null && fCornerControl.getVisible()) {
1689 fCornerControl.setBounds(vbx, hby, vbw, hbh);
73005152
BH
1690 }
1691 updateScrollBarsValues();
3145ec83 1692
73005152 1693 seek--;
df0b8ff4 1694 if (seek == 0) {
eb63f5ff 1695 dontLayout = false;
df0b8ff4 1696 }
73005152
BH
1697 }
1698 }
1699
1700 // static must take place here... cursor is created once.
3145ec83 1701 volatile static Cursor fOverviewCursor;
73005152
BH
1702
1703 /** Support for click-and-see overview shell on this ScrollView */
1704 protected class Overview {
a55887ca 1705
eb63f5ff
BH
1706 /**
1707 * factor for X from real and overview sizes, for mouse move speed.
1708 */
1709 protected float fOverviewFactorX;
1710
1711 /**
1712 * factor for Y from real and overview sizes, for mouse move speed.
1713 */
1714 protected float fOverviewFactorY;
1715 /**
1716 * shell use to show overview
1717 */
1718 protected Shell fOverview;
1719 /**
1720 * save mouse X cursor location for disappear();
1721 */
1722 protected int fSaveCursorX;
1723 /**
1724 * save mouse Y cursor location for disappear();
1725 */
1726 protected int fSaveCursorY;
1727
1728 /**
a55887ca
AM
1729 * Apply overview support on a control. Replace existing corner_widget
1730 *
1731 * @param control
1732 * The control to use
eb63f5ff
BH
1733 */
1734 public void useControl(Control control) {
1735 final Point pos = control.getLocation();
1736 control.addMouseListener(new MouseListener() {
73005152
BH
1737 @Override
1738 public void mouseDoubleClick(MouseEvent e) {
1739 }
1740
1741 @Override
1742 public void mouseDown(MouseEvent e) {
1743 overviewAppear(e.x, e.y);
1744 }
1745
1746 @Override
1747 public void mouseUp(MouseEvent e) {
1748 overviewDisappear();
1749 }
1750 });
1751
eb63f5ff 1752 control.addFocusListener(new FocusListener() {
73005152
BH
1753
1754 @Override
1755 public void focusGained(FocusEvent e) {
73005152
BH
1756 }
1757
1758 @Override
1759 public void focusLost(FocusEvent e) {
a55887ca 1760 if (overviewing()) {
73005152 1761 overviewDisappear(false);
a55887ca 1762 }
73005152
BH
1763 }
1764
1765 });
eb63f5ff 1766 control.addKeyListener(new KeyListener() {
73005152
BH
1767
1768 @Override
eb63f5ff
BH
1769 public void keyPressed(KeyEvent event) {
1770 if (event.keyCode == 32 && !overviewing()) {
73005152 1771 overviewAppear(pos.x, pos.y);
eb63f5ff 1772 } else if (event.keyCode == 32) {
73005152
BH
1773 overviewDisappear();
1774 }
eb63f5ff
BH
1775 if (event.keyCode == SWT.ARROW_DOWN) {
1776 overviewMove(0, 1, event);
73005152
BH
1777 }
1778
eb63f5ff
BH
1779 if (event.keyCode == SWT.ARROW_UP) {
1780 overviewMove(0, -1, event);
73005152
BH
1781 }
1782
eb63f5ff
BH
1783 if (event.keyCode == SWT.ARROW_RIGHT) {
1784 overviewMove(1, 0, event);
73005152
BH
1785 }
1786
eb63f5ff
BH
1787 if (event.keyCode == SWT.ARROW_LEFT) {
1788 overviewMove(-1, 0, event);
73005152
BH
1789 }
1790 }
1791
1792 @Override
1793 public void keyReleased(KeyEvent e) {
1794 }
1795 });
eb63f5ff 1796 control.addMouseMoveListener(new MouseMoveListener() {
73005152
BH
1797 private int refReshCount = 0;
1798 @Override
eb63f5ff 1799 public void mouseMove(MouseEvent event) {
73005152
BH
1800 if (overviewing()) {
1801 // Slow down the refresh
1802 if (refReshCount % 4 == 0) {
eb63f5ff 1803 overviewMove(event);
73005152
BH
1804 }
1805 refReshCount++;
1806 }
1807 }
1808 });
1809 }
1810
a55887ca
AM
1811 /**
1812 * Dispose controls of overview
df0b8ff4 1813 */
73005152 1814 public void dispose() {
eb63f5ff
BH
1815 if (fOverview != null) {
1816 fOverview.dispose();
df0b8ff4 1817 }
73005152
BH
1818 }
1819
a55887ca 1820 /**
df0b8ff4
BH
1821 * @return true if overview is currently on screen
1822 */
73005152 1823 protected boolean overviewing() {
eb63f5ff 1824 return (fOverview != null && fOverview.isVisible());
73005152
BH
1825 }
1826
a55887ca 1827 /**
df0b8ff4 1828 * Process overview appear
a0a88f65
AM
1829 *
1830 * @param mx
1831 * X coordinate
1832 * @param my
1833 * Y coordinate
df0b8ff4 1834 */
73005152 1835 protected void overviewAppear(int mx, int my) {
eb63f5ff
BH
1836 if (fOverview == null) {
1837 fOverview = new Shell(getShell(), SWT.ON_TOP | SWT.NO_BACKGROUND);
1838 fOverview.addPaintListener(new PaintListener() {
73005152
BH
1839 @Override
1840 public void paintControl(PaintEvent e) {
eb63f5ff 1841 drawOverview(e.gc, fOverview.getClientArea());
73005152
BH
1842 }
1843 });
1844 }
1845 // always the same..
1846 // overview.setBackground( viewcontrol_.getBackground() );
eb63f5ff 1847 fOverview.setForeground(fViewControl.getForeground());
73005152
BH
1848
1849 // get location of shell (in screeen coordinates)
eb63f5ff 1850 Point p = toGlobalCoordinates(fCornerControl, 0, 0);
73005152
BH
1851 int x = p.x;
1852 int y = p.y;
1853 int w, h;
eb63f5ff 1854 w = h = fOverviewSize;
73005152 1855 Rectangle scr = getDisplay().getBounds();
eb63f5ff 1856 Point ccs = fCornerControl.getSize();
73005152 1857 try {
eb63f5ff
BH
1858 if (fContentsWidth > fContentsHeight) {
1859 float ratio = fContentsHeight / (float) fContentsWidth;
73005152 1860 h = (int) (w * ratio);
df0b8ff4 1861 if (h < ccs.y) {
73005152 1862 h = ccs.y;
df0b8ff4 1863 } else if (h >= scr.height / 2) {
73005152 1864 h = scr.height / 2;
df0b8ff4 1865 }
73005152 1866 } else {
eb63f5ff 1867 float ratio = fContentsWidth / (float) fContentsHeight;
73005152 1868 w = (int) (h * ratio);
df0b8ff4 1869 if (w < ccs.x) {
73005152 1870 w = ccs.x;
df0b8ff4 1871 } else if (w >= scr.width / 2) {
73005152 1872 w = scr.width / 2;
df0b8ff4 1873 }
73005152 1874 }
eb63f5ff
BH
1875 fOverviewFactorX = fContentsWidth / (float) w;
1876 fOverviewFactorY = fContentsHeight / (float) h;
73005152
BH
1877 }
1878 // no contents size set ?
1879 catch (java.lang.ArithmeticException e) {
1880 }
1881
1882 // try pop-up on button, extending to bottom right,
1883 // if outside screen, extend pop-up to top left
1884 // if( x+w > scr.width ) x = scr.width-w; //x += corner_control_.getSize().x-w;
1885 // if( y+h > scr.height ) y = scr.height-h;//y += corner_control_.getSize().y-h;
df0b8ff4 1886 if (x <= 0) {
73005152 1887 x = 1;
df0b8ff4
BH
1888 }
1889 if (y <= 0) {
73005152 1890 y = 1;
df0b8ff4 1891 }
73005152
BH
1892 x = x - w + ccs.x;
1893 y = y - h + ccs.y;
eb63f5ff
BH
1894 fOverview.setBounds(x, y, w, h);
1895 fOverview.setVisible(true);
1896 fOverview.redraw();
73005152 1897 // mouse cursor disappear, so set invisible mouse cursor ...
eb63f5ff 1898 if (fOverviewCursor == null) {
df0b8ff4 1899 RGB rgb[] = { new RGB(0, 0, 0), new RGB(255, 0, 0) };
eb63f5ff 1900 PaletteData palette = new PaletteData(rgb);
df0b8ff4
BH
1901 int s = 1;
1902 byte src[] = new byte[s * s];
1903 byte msk[] = new byte[s * s];
a55887ca 1904 for (int i = 0; i < s * s; ++i) {
df0b8ff4 1905 src[i] = (byte) 0xFF;
a55887ca 1906 }
eb63f5ff
BH
1907 ImageData i_src = new ImageData(s, s, 1, palette, 1, src);
1908 ImageData i_msk = new ImageData(s, s, 1, palette, 1, msk);
1909 fOverviewCursor = new Cursor(null, i_src, i_msk, 0, 0);
73005152 1910 }
eb63f5ff 1911 fCornerControl.setCursor(fOverviewCursor);
73005152 1912 // convert to global coordinates
eb63f5ff
BH
1913 p = toGlobalCoordinates(fCornerControl, mx, my);
1914 fSaveCursorX = p.x;
1915 fSaveCursorY = p.y;
73005152 1916
eb63f5ff
BH
1917 Rectangle r = fOverview.getClientArea();
1918 int cx = (int) (r.width * fContentsX / (float) fContentsWidth);
1919 int cy = (int) (r.height * fContentsY / (float) fContentsHeight);
73005152
BH
1920
1921 // cx,cy to display's global coordinates
eb63f5ff 1922 p = toGlobalCoordinates(fOverview.getParent(), cx, cy);
73005152
BH
1923 }
1924
a55887ca
AM
1925 /**
1926 * Process disappear of overview
df0b8ff4 1927 */
73005152
BH
1928 protected void overviewDisappear() {
1929 overviewDisappear(true);
1930 }
1931
a55887ca 1932 /**
df0b8ff4 1933 * Process disappear of overview
a55887ca 1934 * @param restoreCursorLoc A flag to restore cursor location
df0b8ff4 1935 */
73005152 1936 protected void overviewDisappear(boolean restoreCursorLoc) {
3145ec83 1937 if (fOverview == null) {
73005152 1938 return;
3145ec83 1939 }
eb63f5ff
BH
1940 fOverview.setVisible(false);
1941 fCornerControl.setCursor(null);
df0b8ff4 1942 if (restoreCursorLoc) {
eb63f5ff 1943 getDisplay().setCursorLocation(fSaveCursorX, fSaveCursorY);
df0b8ff4 1944 }
eb63f5ff
BH
1945 fOverview.dispose();
1946 fOverview = null;
73005152
BH
1947 }
1948
df0b8ff4
BH
1949 /**
1950 * Process mouse move in overview
1951 * @param event The mouse event
1952 */
73005152 1953 protected void overviewMove(MouseEvent event) {
eb63f5ff
BH
1954 Point p = toGlobalCoordinates(fCornerControl, event.x, event.y);
1955 int dx = p.x - fSaveCursorX;
1956 int dy = p.y - fSaveCursorY;
73005152
BH
1957 overviewMove(dx, dy, event);
1958 }
1959
a55887ca 1960 /**
df0b8ff4 1961 * Process mouse move event when overviewing
a55887ca 1962 *
df0b8ff4
BH
1963 * @param dx The x coordinates delta
1964 * @param dy The y coordinates delta
1965 * @param event The typed event
1966 */
73005152
BH
1967 protected void overviewMove(int dx, int dy, TypedEvent event) {
1968 boolean ctrl = false;
1969 boolean shift = false;
1970
1971 if (event instanceof MouseEvent) {
1972 MouseEvent e = (MouseEvent) event;
eb63f5ff 1973 getDisplay().setCursorLocation(fSaveCursorX, fSaveCursorY);
73005152
BH
1974 ctrl = (e.stateMask & SWT.CONTROL) != 0;
1975 shift = (e.stateMask & SWT.SHIFT) != 0;
1976 } else if (event instanceof KeyEvent) {
1977 KeyEvent e = (KeyEvent) event;
1978 ctrl = (e.stateMask & SWT.CONTROL) != 0;
1979 shift = (e.stateMask & SWT.SHIFT) != 0;
1980 }
1981
eb63f5ff
BH
1982 int cx = fContentsX;
1983 int cy = fContentsY;
1984 float fx = fOverviewFactorX;
1985 float fy = fOverviewFactorY;
73005152
BH
1986
1987 if (ctrl && shift) {
1988 if ((fx * 0.25f > 1) && (fy * 0.25 > 1)) {
1989 fx = fy = 1.0f;
1990 } else {
1991 fx *= 0.1f;
1992 fy *= 0.1f;
1993 }
1994 } else if (ctrl) {
1995 fx *= 0.5f;
1996 fy *= 0.5f;
1997 } else if (shift) {
1998 fx *= 0.5f;
1999 fy *= 0.5f;
2000 }
2001 scrollBy((int) (fx * dx), (int) (fy * dy));
eb63f5ff
BH
2002 if (cx != fContentsX || cy != fContentsY) {
2003 fOverview.redraw();
2004 fOverview.update(); // draw now !
73005152
BH
2005 }
2006 }
2007
df0b8ff4
BH
2008 /**
2009 * Convert overview coordinates to global coordinates.
a55887ca 2010 *
a0a88f65
AM
2011 * @param loc
2012 * the control reference
2013 * @param x
2014 * The x coordinate to convert
2015 * @param y
2016 * The y coordinate to convert
2017 * @return The new converted Point
df0b8ff4 2018 */
eb63f5ff
BH
2019 protected Point toGlobalCoordinates(Control loc, int x, int y) {
2020 Point p = new Point(x, y);
2021 for (Control c = loc; c != null; c = c.getParent()) {
73005152
BH
2022 // control might have client area with 'decorations'
2023 int trim_x = 0, trim_y = 0;
2024 // other kind of widget with trimming ??
2025 if (c instanceof Scrollable) {
2026 Scrollable s = (Scrollable) c;
2027 Rectangle rr = s.getClientArea();
2028 Rectangle tr = s.computeTrim(rr.x, rr.y, rr.width, rr.height);
2029 trim_x = rr.x - tr.x;
2030 trim_y = rr.y - tr.y;
2031 }
2032 p.x += c.getLocation().x + trim_x;
2033 p.y += c.getLocation().y + trim_y;
2034 }
2035 return p;
2036 }
2037 }
2038}
This page took 0.138478 seconds and 5 git commands to generate.