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