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