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