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