1 /**********************************************************************
2 * Copyright (c) 2005, 2013 IBM Corporation, Ericsson
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM - Initial API and implementation
10 * Bernd Hufmann - Updated for TMF
11 **********************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
;
15 import java
.util
.Timer
;
16 import java
.util
.TimerTask
;
18 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.util
.SDMessages
;
19 import org
.eclipse
.swt
.SWT
;
20 import org
.eclipse
.swt
.events
.ControlListener
;
21 import org
.eclipse
.swt
.events
.FocusEvent
;
22 import org
.eclipse
.swt
.events
.FocusListener
;
23 import org
.eclipse
.swt
.events
.KeyEvent
;
24 import org
.eclipse
.swt
.events
.KeyListener
;
25 import org
.eclipse
.swt
.events
.MouseEvent
;
26 import org
.eclipse
.swt
.events
.MouseListener
;
27 import org
.eclipse
.swt
.events
.MouseMoveListener
;
28 import org
.eclipse
.swt
.events
.MouseTrackListener
;
29 import org
.eclipse
.swt
.events
.PaintEvent
;
30 import org
.eclipse
.swt
.events
.PaintListener
;
31 import org
.eclipse
.swt
.events
.SelectionEvent
;
32 import org
.eclipse
.swt
.events
.SelectionListener
;
33 import org
.eclipse
.swt
.events
.TypedEvent
;
34 import org
.eclipse
.swt
.graphics
.Color
;
35 import org
.eclipse
.swt
.graphics
.Cursor
;
36 import org
.eclipse
.swt
.graphics
.GC
;
37 import org
.eclipse
.swt
.graphics
.ImageData
;
38 import org
.eclipse
.swt
.graphics
.PaletteData
;
39 import org
.eclipse
.swt
.graphics
.Point
;
40 import org
.eclipse
.swt
.graphics
.RGB
;
41 import org
.eclipse
.swt
.graphics
.Rectangle
;
42 import org
.eclipse
.swt
.widgets
.Button
;
43 import org
.eclipse
.swt
.widgets
.Canvas
;
44 import org
.eclipse
.swt
.widgets
.Composite
;
45 import org
.eclipse
.swt
.widgets
.Control
;
46 import org
.eclipse
.swt
.widgets
.Display
;
47 import org
.eclipse
.swt
.widgets
.Layout
;
48 import org
.eclipse
.swt
.widgets
.ScrollBar
;
49 import org
.eclipse
.swt
.widgets
.Scrollable
;
50 import org
.eclipse
.swt
.widgets
.Shell
;
53 * ScrollView widget provides a scrolling area with on-demand scroll bars.
54 * Overview scrollable panel can be used (@see setOverviewEnabled()).
56 * @author Eric Miravete
59 public class ScrollView
extends Composite
{
61 // ------------------------------------------------------------------------
63 // ------------------------------------------------------------------------
65 // Value for scroll bar mode, default is AUTO
67 * Scroll bar mode AUTO
69 public static final int AUTO
= 0;
71 * Scroll bar mode ALWAYS_ON
73 public static final int ALWAYS_ON
= 1;
75 * Scroll bar mode ALWAYS_OFF
77 public static final int ALWAYS_OFF
= 2;
79 * Bit mask for visible vertical scroll bar
81 public static final int VBAR
= 0x01;
83 * Bit mask for visible horizontal scroll bar
85 public static final int HBAR
= 0x02;
87 * Value of the contents height property.
89 protected int fContentsHeight
= 0;
91 * Value of the contents width property.
93 protected int fContentsWidth
= 0;
95 * Value of the contents x coordinate property
97 protected int fContentsX
= 0;
99 * Value of the contents y coordinate property
101 protected int fContentsY
= 0;
103 * Scroll bar mode of horizontal scroll bar.
105 protected int fHorScrollbarMode
= AUTO
;
107 * Scroll bar mode of vertical scroll bar.
109 protected int fVertScrollbarMode
= AUTO
;
111 * Increment for the horizontal scroll bar.
113 protected int fHorScrollbarIncrement
= 10;
115 * Increment for the vertical scroll bar.
117 protected int fVertScrollbarIncrement
= 10;
119 * Flag whether auto scroll is enabled or not.
121 protected boolean fAutoScrollEnabled
= true;
123 * Value of the auto scroll period.
125 protected int fAutoScrollPeriod
= 75;
127 * The local paint listener reference.
129 protected PaintListener fLocalPaintListener
= null;
131 * The local mouse move listener reference.
133 protected MouseMoveListener fLocalMouseMoveListener
= null;
135 * The local mouse listener reference.
137 protected MouseListener fLocalMouseListener
= null;
139 * The local control listener reference.
141 protected ControlListener fLocalControlListener
= null;
143 * The local key listener reference.
145 protected KeyListener fLocalKeyListener
= null;
146 // Canvas for vertical/horizontal Scroll Bar only ... because new ScrollBar() does works.
148 * Canvas for horizontal scroll bar.
150 protected Canvas fHorScrollBar
;
152 * Canvas for vertical scroll bar.
154 protected Canvas fVertScrollBar
;
156 * Canvas for the view control.
158 protected Canvas fViewControl
;
160 * Control used in the bottom right corner @see setCornerControl() and @see setOverviewEnabled(true)
162 protected Control fCornerControl
;
164 * Size of overview widget.
166 protected int fOverviewSize
= 100; // default size for overview
168 * Timer for auto_scroll feature
170 protected AutoScroll fAutoScroll
= null;
172 * TimerTask for auto_scroll feature !=null when auto scroll is running
174 protected Timer fAutoScrollTimer
= null;
176 * where mouse down appear on contents area (x coordinate)
178 protected int fMouseDownX
= -1;
180 * where mouse down appear on contents area (y coordinate)
182 protected int fMousDownY
= -1;
185 // ------------------------------------------------------------------------
187 // ------------------------------------------------------------------------
190 * Create a ScrollView, child of composite c. Both scroll bar have the mode AUTO. Auto scroll feature is enabled
191 * using a delay of 250ms. Overview feature is not enabled by default (use setOverviewEnabled()).
193 * @param c The parent composite
194 * @param style The SWT style bits @see SWT
196 public ScrollView(Composite c
, int style
) {
197 this(c
, style
, true);
201 * Create a ScrollView, child of composite c. Both scroll bar have the mode AUTO. Auto scroll feature is enabled
202 * using a delay of 250ms. Overview feature is not enabled by default (use setOverviewEnabled()).
204 * @param c The parent composite.
205 * @param style The SWT style bits @see SWT
206 * @param mouseWheel Flag to force scrollView to handles mouse wheel
208 public ScrollView(Composite c
, int style
, boolean mouseWheel
) {
209 super(c
, SWT
.NONE
); // style&(~(SWT.H_SCROLL|SWT.V_SCROLL)));
211 fHorScrollBar
= new Canvas(this, SWT
.H_SCROLL
);
213 // force scroll bar to get mouse wheel, those scrollbar will be hidden
214 fViewControl
= new Canvas(this, style
| SWT
.H_SCROLL
| SWT
.V_SCROLL
);
216 fViewControl
= new Canvas(this, style
);
218 fViewControl
.setBackground(getBackground());
219 // hide scroll bar as their are replaced by fHorScrollBar and fVertScrollBar.
221 fViewControl
.getVerticalBar().setVisible(false);
222 fViewControl
.getHorizontalBar().setVisible(false);
224 fVertScrollBar
= new Canvas(this, SWT
.V_SCROLL
);
225 // make fVerScrollBar able to receive mouse wheel
226 // does not help as we can't set a MouseListener on fVerScrollBar.getVerticalBar()
227 // to set focus on viewcontrol_
228 // fVerScrollBar.addKeyListener( new KeyAdapter() {});
230 setLayout(new SVLayout());
232 fLocalPaintListener
= new PaintListener() {
234 public void paintControl(PaintEvent event
) {
235 // use clipping, to reduce cost of paint.
236 Rectangle r
= event
.gc
.getClipping();
237 int cx
= viewToContentsX(r
.x
);
238 int cy
= viewToContentsY(r
.y
);
239 drawContents(event
.gc
, cx
, cy
, r
.width
, r
.height
);
242 fViewControl
.addPaintListener(fLocalPaintListener
);
244 fLocalMouseMoveListener
= new MouseMoveListener() {
246 public void mouseMove(MouseEvent e
) {
247 int ox
= e
.x
, oy
= e
.y
;
248 e
.x
= viewToContentsX(e
.x
);
249 e
.y
= viewToContentsY(e
.y
);
250 contentsMouseMoveEvent(e
);
256 fViewControl
.addMouseMoveListener(fLocalMouseMoveListener
);
258 MouseTrackListener localMouseTrackListener
= new MouseTrackListener() {
260 public void mouseEnter(MouseEvent e
) {
261 int ox
= e
.x
, oy
= e
.y
;
262 e
.x
= viewToContentsX(e
.x
);
263 e
.y
= viewToContentsY(e
.y
);
264 contentsMouseEnter(e
);
270 public void mouseHover(MouseEvent e
) {
271 int ox
= e
.x
, oy
= e
.y
;
272 e
.x
= viewToContentsX(e
.x
);
273 e
.y
= viewToContentsY(e
.y
);
274 contentsMouseHover(e
);
280 public void mouseExit(MouseEvent e
) {
281 int ox
= e
.x
, oy
= e
.y
;
282 e
.x
= viewToContentsX(e
.x
);
283 e
.y
= viewToContentsY(e
.y
);
284 contentsMouseExit(e
);
291 fViewControl
.addMouseTrackListener(localMouseTrackListener
);
293 fLocalMouseListener
= new MouseListener() {
295 public void mouseDoubleClick(MouseEvent e
) {
296 int ox
= e
.x
, oy
= e
.y
;
297 e
.x
= viewToContentsX(e
.x
);
298 e
.y
= viewToContentsY(e
.y
);
299 contentsMouseDoubleClickEvent(e
);
305 public void mouseDown(MouseEvent e
) {
306 int ox
= e
.x
, oy
= e
.y
;
307 e
.x
= fMouseDownX
= viewToContentsX(e
.x
);
308 e
.y
= fMousDownY
= viewToContentsY(e
.y
);
309 contentsMouseDownEvent(e
);
315 public void mouseUp(MouseEvent e
) {
316 int ox
= e
.x
, oy
= e
.y
;
317 e
.x
= viewToContentsX(e
.x
);
318 e
.y
= viewToContentsY(e
.y
);
319 contentsMouseUpEvent(e
);
322 // here because class extenting me can catch mouse Up and want to scroll...
323 fMouseDownX
= fMousDownY
= -1;
326 fViewControl
.addMouseListener(fLocalMouseListener
);
328 fLocalKeyListener
= new KeyListener() {
330 public void keyPressed(KeyEvent e
) {
335 public void keyReleased(KeyEvent e
) {
340 fViewControl
.addKeyListener(fLocalKeyListener
);
342 getVerticalBar().addSelectionListener(new SelectionListener() {
344 public void widgetSelected(SelectionEvent e
) {
345 setContentsPos(fContentsX
, getVerticalBar().getSelection());
346 // need to change "hidden" vertical bar value ?
347 // force focus on fViewControl so we got future mouse wheel's scroll events
348 if (!fViewControl
.isFocusControl()) {
349 fViewControl
.setFocus();
354 public void widgetDefaultSelected(SelectionEvent e
) {
358 if (fViewControl
.getVerticalBar() != null) {
359 // add fViewControl hidden scrollbar listener to get mouse wheel ...
360 fViewControl
.getVerticalBar().addSelectionListener(new SelectionListener() {
362 public void widgetSelected(SelectionEvent e
) {
363 ScrollBar b
= fViewControl
.getVerticalBar();
364 setContentsPos(fContentsX
, b
.getSelection());
365 // change "real" vertical bar selection too
366 getVerticalBar().setSelection(b
.getSelection());
370 public void widgetDefaultSelected(SelectionEvent e
) {
374 getHorizontalBar().addSelectionListener(new SelectionListener() {
376 public void widgetSelected(SelectionEvent e
) {
377 setContentsPos(getHorizontalBar().getSelection(), fContentsY
);
378 // need to change "real" horizontal bar too ?
379 // force focus on fViewControl so we got future mouse wheel's scroll events
380 if (!fViewControl
.isFocusControl()) {
381 fViewControl
.setFocus();
386 public void widgetDefaultSelected(SelectionEvent e
) {
389 if (fViewControl
.getHorizontalBar() != null) {
390 fViewControl
.getHorizontalBar().addSelectionListener(new SelectionListener() {
392 public void widgetSelected(SelectionEvent e
) {
393 ScrollBar b
= fViewControl
.getHorizontalBar();
394 setContentsPos(b
.getSelection(), fContentsY
);
395 // change "real" vertical bar selection too
396 getHorizontalBar().setSelection(b
.getSelection());
400 public void widgetDefaultSelected(SelectionEvent e
) {
406 // ------------------------------------------------------------------------
408 // ------------------------------------------------------------------------
412 * @see org.eclipse.swt.widgets.Composite#setFocus()
415 public boolean setFocus() {
416 return fViewControl
.forceFocus();
421 * @see org.eclipse.swt.widgets.Control#setCursor(org.eclipse.swt.graphics.Cursor)
424 public void setCursor(Cursor cursor
) {
425 fViewControl
.setCursor(cursor
);
429 * Dispose controls used in scroll view
432 * @see org.eclipse.swt.widgets.Widget#dispose()
435 public void dispose() {
436 if (fAutoScroll
!= null) {
437 fAutoScroll
.cancel();
440 if (fViewControl
!= null) {
441 fViewControl
.dispose();
444 if (fVertScrollBar
!= null) {
445 fVertScrollBar
.dispose();
447 fVertScrollBar
= null;
448 if (fHorScrollBar
!= null) {
449 fHorScrollBar
.dispose();
451 fHorScrollBar
= null;
452 if (fCornerControl
!= null) {
453 Object data
= fCornerControl
.getData();
454 if (data
instanceof Overview
) {
455 ((Overview
) data
).dispose();
457 fCornerControl
.dispose();
458 fCornerControl
= null;
465 * @see org.eclipse.swt.widgets.Composite#getClientArea()
468 public Rectangle
getClientArea() {
469 return fViewControl
.getClientArea();
474 * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color)
477 public void setBackground(Color c
) {
478 super.setBackground(c
);
479 fViewControl
.setBackground(c
);
484 * @see org.eclipse.swt.widgets.Control#setToolTipText(java.lang.String)
487 public void setToolTipText(String text
) {
488 fViewControl
.setToolTipText(text
);
492 * Draw overview area, @see setOverviewEnabled. By default draw a rectangle corresponding to the visible area of
493 * scroll view. You can redefine this method to draw the contents as drawContents does... ...in an other magnify
496 * @param gc GC to used to draw.
497 * @param r Rectangle corresponding to the client area of overview.
499 protected void drawOverview(GC gc
, Rectangle r
) {
500 int x
= (int) (r
.width
* fContentsX
/ (float) fContentsWidth
);
501 int y
= (int) (r
.height
* fContentsY
/ (float) fContentsHeight
);
502 int vw
= getVisibleWidth();
503 int vh
= getVisibleHeight();
505 if (fContentsWidth
> vw
) {
506 w
= (int) (r
.width
* vw
/ (float) fContentsWidth
);
508 int h
= r
.height
- 1;
509 if (fContentsHeight
> vh
) {
510 h
= (int) (r
.height
* vh
/ (float) fContentsHeight
);
513 gc
.setForeground(getForeground());
514 // too small rectangle ?
515 if (w
< 5 || h
< 5) {
517 gc
.drawLine(x
, 0, x
, r
.height
);
518 gc
.drawLine(0, y
, r
.width
, y
);
520 gc
.drawRectangle(x
, y
, w
, h
);
525 * Remove the local Listener and add the new listener.
527 * @param nlistener the new listener
529 public void replaceControlListener(ControlListener nlistener
) {
530 if (fLocalControlListener
!= null) {
531 removeControlListener(fLocalControlListener
);
532 fLocalControlListener
= null;
534 addControlListener(nlistener
);
538 * Remove the local Listener and add the new listener.
540 * @param nlistener the new listener
542 public void replaceKeyListener(KeyListener nlistener
) {
543 if (fLocalKeyListener
!= null) {
544 removeKeyListener(fLocalKeyListener
);
545 fLocalKeyListener
= null;
547 addKeyListener(nlistener
);
551 * Remove the local Listener and add the new listener.
553 * @param nlistener the new listener
555 public void replaceMouseListener(MouseListener nlistener
) {
556 if (fLocalMouseListener
!= null) {
557 removeMouseListener(fLocalMouseListener
);
558 fLocalMouseListener
= null;
560 fViewControl
.addMouseListener(nlistener
);
564 * Remove the local Listener and add the new listener.
566 * @param nlistener the new listener
568 public void replaceMouseMoveListener(MouseMoveListener nlistener
) {
569 if (fLocalMouseMoveListener
!= null) {
570 removeMouseMoveListener(fLocalMouseMoveListener
);
571 fLocalMouseMoveListener
= null;
573 fViewControl
.addMouseMoveListener(nlistener
);
577 * Remove the local Listener and add the new listener.
579 * @param nlistener the new listener
581 public void replacePaintListener(PaintListener nlistener
) {
582 if (fLocalPaintListener
!= null) {
583 removePaintListener(fLocalPaintListener
);
584 fLocalPaintListener
= null;
586 fViewControl
.addPaintListener(nlistener
);
590 * Access method for the contentsHeight property.
592 * @return the current value of the contentsHeight property
594 public int getContentsHeight() {
595 return fContentsHeight
;
599 * Access method for the contentsWidth property.
601 * @return the current value of the contentsWidth property
603 public int getContentsWidth() {
604 return fContentsWidth
;
608 * Access method for the contentsX property.
610 * @return the current value of the contentsX property
612 public int getContentsX() {
617 * Access method for the contentsY property.
619 * @return the current value of the contentsY property
621 public int getContentsY() {
626 * Determines if the dragAutoScroll property is true.
628 * @return <code>true<code> if the dragAutoScroll property is true
630 public boolean isDragAutoScroll() {
631 return fAutoScrollEnabled
;
635 * Sets the value of the dragAutoScroll property.
637 * @param aDragAutoScroll the new value of the dragAutoScroll property
639 public void setDragAutoScroll(boolean aDragAutoScroll
) {
640 fAutoScrollEnabled
= aDragAutoScroll
;
641 if (!fAutoScrollEnabled
&& (fAutoScroll
!= null)) {
642 fAutoScroll
.cancel();
648 * Change delay (in millisec) used for auto scroll feature.
650 * @param period new period between to auto scroll
652 public void setDragAutoScrollPeriod(int period
) {
653 fAutoScrollPeriod
= Math
.max(0, period
);
657 * Return auto scroll period.
661 public int getDragAutoScrollPeriod() {
662 return fAutoScrollPeriod
;
666 * Access method for the hScrollBarMode property.
668 * @return the current value of the hScrollBarMode property
670 public int getHScrollBarMode() {
671 return fHorScrollbarMode
;
675 * Sets the value of the hScrollBarMode property.
677 * @param aHScrollBarMode the new value of the hScrollBarMode property
679 public void setHScrollBarMode(int aHScrollBarMode
) {
680 fHorScrollbarMode
= aHScrollBarMode
;
684 * Access method for the vScrollBarMode property.
686 * @return the current value of the vScrollBarMode property
688 public int getVScrollBarMode() {
689 return fVertScrollbarMode
;
693 * Sets the value of the vScrollBarMode property.
695 * @param aVScrollBarMode the new value of the vScrollBarMode property
697 public void setVScrollBarMode(int aVScrollBarMode
) {
698 fVertScrollbarMode
= aVScrollBarMode
;
702 * Return horizontal scroll bar increment, default:1
704 * @return The increment
706 public int getHScrollBarIncrement() {
707 return fHorScrollbarIncrement
;
711 * Return vertical scroll bar increment, default:1
713 * @return The increment
715 public int getVScrollBarIncrement() {
716 return fVertScrollbarIncrement
;
720 * Change horizontal scroll bar increment, minimum:1. Page increment is
721 * always set to visible width.
724 * Increment value to set
726 public void setHScrollBarIncrement(int inc
) {
727 fHorScrollbarIncrement
= Math
.max(1, inc
);
731 * Change vertical scroll bar increment, minimum:1. Page increment is always
732 * set to visible height.
735 * Increment value to set
737 public void setVScrollBarIncrement(int inc
) {
738 fVertScrollbarIncrement
= Math
.max(1, inc
);
742 * Enable or disable overview feature. Enabling overview, dispose and replace existing corner control by a button.
743 * Clicking in it open overview, move mouse cursor holding button to move scroll view and release button to hide
744 * overview. Tip: hold control and/or shift key while moving mouse when overview is open made fine scroll.
746 * @param value true to engage overview feature
748 public void setOverviewEnabled(boolean value
) {
749 if (isOverviewEnabled() == value
) {
755 Button b
= new Button(this, SWT
.NONE
);
756 b
.setText("+"); //$NON-NLS-1$
757 Overview ovr
= new Overview();
761 b
.setToolTipText(SDMessages
._78
);
763 setCornerControl(cc
);
767 * Change overview size (at ratio 1:1), default is 100
772 public void setOverviewSize(int size
) {
773 fOverviewSize
= Math
.abs(size
);
777 * Returns whether the overview is enabled or not.
779 * @return true is overview feature is enabled
781 public boolean isOverviewEnabled() {
782 if (fCornerControl
instanceof Button
) {
783 Object data
= ((Button
) fCornerControl
).getData();
785 if (data
instanceof Overview
) {
793 * Returns the overview size at ratio 1:1.
795 * @return current overview size at ratio 1:1
797 public int getOverviewSize() {
798 return fOverviewSize
;
802 * Returns control used to display view (might not be this object). Use this control to add/remove listener on the
805 * @return control used to display view (might not be this object).
807 public Control
getViewControl() {
812 * Called when the mouse enter the ScrollView area
817 protected void contentsMouseExit(MouseEvent e
) {
821 * Called when the mouse enter the ScrollView area after and system defined
827 protected void contentsMouseHover(MouseEvent e
) {
831 * Called when the mouse enter the ScrollView area
836 protected void contentsMouseEnter(MouseEvent e
) {
840 * Called when user double on contents area.
845 protected void contentsMouseDoubleClickEvent(MouseEvent e
) {
849 * Called when mouse is on contents area and button is pressed.
854 protected void contentsMouseDownEvent(MouseEvent e
) {
860 * TimerTask for auto scroll feature.
862 protected static class AutoScroll
extends TimerTask
{
870 /** ScrollView object */
871 public ScrollView scrollView
;
877 * ScrollView object to use
883 public AutoScroll(ScrollView sv
, int dx
, int dy
) {
891 Display
.getDefault().asyncExec(new Runnable() {
894 scrollView
.scrollBy(deltaX
, deltaY
);
901 * Called when mouse is on contents area and mode.
906 protected void contentsMouseMoveEvent(MouseEvent event
) {
907 if ((event
.stateMask
& SWT
.BUTTON_MASK
) != 0) {
908 if (!fAutoScrollEnabled
) {
909 scrollBy(-(event
.x
- fMouseDownX
), -(event
.y
- fMousDownY
));
915 int v_right
= getContentsX() + getVisibleWidth();
916 int v_bottom
= getContentsY() + getVisibleHeight();
919 if (event
.x
< getContentsX()) {
920 sx
= (getContentsX() - event
.x
);
921 fMouseDownX
= getContentsX();
922 } else if (event
.x
> v_right
) {
923 sx
= -event
.x
+ v_right
;
924 fMouseDownX
= v_right
;
926 if (event
.y
< getContentsY()) {
927 sy
= (getContentsY() - event
.y
);
928 fMousDownY
= getContentsY();
929 } else if (event
.y
> v_bottom
) {
930 sy
= -event
.y
+ v_bottom
;
931 fMousDownY
= v_bottom
;
934 if (sx
!= 0 || sy
!= 0) {
935 // start auto scroll...
936 if (fAutoScroll
== null) {
937 if (fAutoScrollTimer
== null) {
938 fAutoScrollTimer
= new Timer(true);
940 fAutoScroll
= new AutoScroll(this, sx
, sy
);
941 fAutoScrollTimer
.schedule(fAutoScroll
, 0, fAutoScrollPeriod
);
943 fAutoScroll
.deltaX
= sx
;
944 fAutoScroll
.deltaY
= sy
;
947 if (fAutoScroll
!= null) {
948 fAutoScroll
.cancel();
952 scrollBy(-(event
.x
- fMouseDownX
), -(event
.y
- fMousDownY
));
958 * Called when mouse is on contents area and button is released
963 protected void contentsMouseUpEvent(MouseEvent event
) {
964 // reset auto scroll if it's engaged
965 if (fAutoScroll
!= null) {
966 fAutoScroll
.cancel();
972 * Responsible to draw contents area. At least rectangle clipX must be
973 * redrawn. This rectangle is given in contents coordinates. By default, no
987 protected void drawContents(GC gc
, int clipx
, int clipy
, int clipw
, int cliph
) {
991 * Change the size of the contents area.
993 * @param width new width of the area.
994 * @param height new height of the area.
996 public void resizeContents(int width
, int height
) {
997 int localWidth
= width
;
998 int localHeight
= height
;
1000 if (localWidth
< 0) {
1003 if (localHeight
< 0) {
1007 int oldW
= fContentsWidth
;
1008 int oldH
= fContentsHeight
;
1010 if (localWidth
== oldW
&& localHeight
== oldH
) {
1014 fContentsWidth
= localWidth
;
1015 fContentsHeight
= localHeight
;
1017 if (oldW
> localWidth
) {
1023 int vis_width
= getVisibleWidth();
1024 int vis_height
= getVisibleHeight();
1025 if (oldW
< vis_width
) {
1026 if (localWidth
> vis_width
) {
1027 localWidth
= vis_width
;
1029 fViewControl
.redraw(getContentsX() + oldW
, 0, localWidth
- oldW
, vis_height
, true);
1032 if (oldH
> localHeight
) {
1033 int s
= localHeight
;
1038 if (oldH
< vis_height
) {
1039 if (localHeight
> vis_height
) {
1040 localHeight
= vis_height
;
1042 fViewControl
.redraw(0, getContentsY() + oldH
, vis_width
, localHeight
- oldH
, true);
1044 if (updateScrollBarVisiblity()) {
1047 updateScrollBarsValues();
1051 // redefined for internal use ..
1053 public void redraw() {
1055 // ..need to redraw this already:
1056 fViewControl
.redraw();
1060 * @param delataX The delta in X
1061 * @param deltaY the delta in Y
1063 public void scrollBy(int delataX
, int deltaY
) {
1064 setContentsPos(getContentsX() + delataX
, getContentsY() + deltaY
);
1068 * Scroll to ensure point(in contents coordinates) is visible.
1070 * @param px Point's x position
1071 * @param py Point's y position
1073 public void ensureVisible(int px
, int py
) {
1074 int cx
= getContentsX(), cy
= getContentsY();
1075 int right
= getContentsX() + getVisibleWidth();
1076 int bottom
= getContentsY() + getVisibleHeight();
1077 if (px
< getContentsX()) {
1079 } else if (px
> right
) {
1080 cx
= px
- getVisibleWidth();
1082 if (py
< getContentsY()) {
1084 } else if (py
> bottom
) {
1085 cy
= py
- getVisibleHeight();
1087 setContentsPos(cx
, cy
);
1091 * Make rectangle (x,y,w,h, in contents coordinates) visible. if rectangle cannot be completely visible, use
1094 * @param xValue x contents coordinates of rectangle.
1095 * @param yValue y contents coordinates of rectangle.
1096 * @param width width of rectangle.
1097 * @param height height of rectangle.
1098 * @param align bit or'ed SWT flag like SWT.LEFT,RIGHT,CENTER,TOP,BOTTOM,VERTICAL used only for bigger rectangle
1099 * than visible area. By default CENTER/VERTICAL
1101 public void ensureVisible(int xValue
, int yValue
, int width
, int height
, int align
) {
1102 ensureVisible(xValue
, yValue
, width
, height
, align
, false);
1106 * Make rectangle (xValue,yValue,width,height, in contents coordinates) visible. if rectangle cannot be completely visible, use
1109 * @param xValue x contents coordinates of rectangle.
1110 * @param yValue y contents coordinates of rectangle.
1111 * @param width width of rectangle.
1112 * @param height height of rectangle.
1113 * @param align bit or'ed SWT flag like SWT.LEFT,RIGHT,CENTER,TOP,BOTTOM,VERTICAL used only for bigger rectangle
1114 * than visible area. By default CENTER/VERTICAL
1115 * @param forceAlign force alignment for rectangle smaller than the visible area
1117 protected void ensureVisible(int xValue
, int yValue
, int width
, int height
, int align
, boolean forceAlign
) {
1119 int localX
= xValue
;
1120 int localY
= yValue
;
1121 int localWidth
= width
;
1122 int localHeight
= height
;
1124 if (localWidth
< 0) {
1125 localX
= localX
+ localWidth
;
1126 localWidth
= -localWidth
;
1128 if (localHeight
< 0) {
1129 localY
= localY
+ localHeight
;
1130 localHeight
= -localHeight
;
1132 int hbar
= getHorizontalBarHeight();
1133 int vbar
= getVerticalBarWidth();
1134 int cx
= getContentsX();
1135 int cy
= getContentsY();
1136 int right
= getContentsX() + getVisibleWidth() - vbar
;
1137 int bottom
= getContentsY() + getVisibleHeight() - hbar
;
1138 boolean align_h
= false, align_v
= false;
1140 if (localX
< getContentsX()) {
1142 } else if (localX
+ localWidth
> right
) {
1143 cx
= localX
- localWidth
;
1145 if (localY
< getContentsY()) {
1147 } else if (localY
+ localHeight
> bottom
) {
1148 cy
= localY
- localHeight
;
1151 if (localWidth
> getVisibleWidth()) {
1154 if (localHeight
> getVisibleHeight()) {
1157 // compute alignment on visible area horizontally
1158 if (align_h
|| (forceAlign
&& localX
+ localWidth
> right
)) {
1160 if ((align
& SWT
.LEFT
) != 0) {
1162 } else if ((align
& SWT
.RIGHT
) != 0) {
1163 cx
= right
- localWidth
;
1165 cx
= localX
+ (localWidth
- getVisibleWidth()) / 2;
1168 // compute alignment on visible area vertically
1169 if (align_v
|| (forceAlign
&& localY
+ localHeight
> bottom
)) {
1171 if ((align
& SWT
.TOP
) != 0) {
1173 } else if ((align
& SWT
.BOTTOM
) != 0) {
1174 cy
= bottom
- localHeight
;
1176 cy
= localY
+ (localHeight
- getVisibleHeight()) / 2;
1179 setContentsPos(cx
, cy
);
1183 * Returns true if point is visible (expressed in contents coordinates).
1185 * @param px Point's x position
1186 * @param py Point's y position
1187 * @return true if point is visible (expressed in contents coordinates)
1189 public boolean isVisible(int px
, int py
) {
1190 if (px
< getContentsX()) {
1193 if (py
< getContentsY()) {
1196 if (px
> (getContentsX() + getVisibleWidth())) {
1199 if (py
> (getContentsY() + getVisibleHeight())) {
1206 * Returns true if rectangle if partially visible.
1208 * @param xValue x contents coordinates of rectangle.
1209 * @param yValue y contents coordinates of rectangle.
1210 * @param width width of rectangle.
1211 * @param height height of rectangle.
1212 * @return true if rectangle if partially visible.
1214 public boolean isVisible(int xValue
, int yValue
, int width
, int height
) {
1215 if (xValue
+ width
< getContentsX()) {
1218 if (yValue
+ height
< getContentsY()) {
1221 int vr
= getContentsX() + getVisibleWidth();
1222 int vb
= getContentsY() + getVisibleHeight();
1233 * Returns visible part of rectangle, or null if rectangle is not visible.
1234 * Rectangle is expressed in contents coordinates.
1237 * x contents coordinates of rectangle.
1239 * y contents coordinates of rectangle.
1241 * width of rectangle.
1243 * height of rectangle.
1244 * @return visible part of rectangle, or null if rectangle is not visible.
1246 public Rectangle
getVisiblePart(int xValue
, int yValue
, int width
, int height
) {
1247 if (xValue
+ width
< getContentsX()) {
1250 if (yValue
+ height
< getContentsY()) {
1253 int vr
= getContentsX() + getVisibleWidth();
1254 int vb
= getContentsY() + getVisibleHeight();
1261 int rr
= xValue
+ width
, rb
= yValue
+ height
;
1262 int nl
= Math
.max(xValue
, getContentsX()), nt
= Math
.max(yValue
, getContentsY()), nr
= Math
.min(rr
, vr
), nb
= Math
.min(rb
, vb
);
1263 return new Rectangle(nl
, nt
, nr
- nl
, nb
- nt
);
1267 * Returns the visible part for given rectangle.
1269 * @param rect A rectangle
1271 * @return gets visible part of rectangle (or <code>null</code>)
1273 public final Rectangle
getVisiblePart(Rectangle rect
) {
1277 return getVisiblePart(rect
.x
, rect
.y
, rect
.width
, rect
.height
);
1281 * Change top left position of visible area. Check if the given point is inside contents area.
1283 * @param xValue x contents coordinates of visible area.
1284 * @param yValue y contents coordinates of visible area.
1285 * @return true if view really moves
1287 public boolean setContentsPos(int xValue
, int yValue
) {
1288 int nx
= xValue
, ny
= yValue
;
1289 if (getVisibleWidth() >= getContentsWidth()) {
1294 } else if (xValue
+ getVisibleWidth() > getContentsWidth()) {
1295 nx
= getContentsWidth() - getVisibleWidth();
1298 if (getVisibleHeight() >= getContentsHeight()) {
1303 } else if (yValue
+ getVisibleHeight() > getContentsHeight()) {
1304 ny
= getContentsHeight() - getVisibleHeight();
1308 if (nx
== fContentsX
&& ny
== fContentsY
) {
1313 updateScrollBarsValues();
1314 // ? find smallest area to redraw only them ?
1315 fViewControl
.redraw();
1319 // redefined to return our vertical bar
1322 * @see org.eclipse.swt.widgets.Scrollable#getVerticalBar()
1325 public ScrollBar
getVerticalBar() {
1326 return fVertScrollBar
.getVerticalBar();
1329 // redefined to return out horizontal bar
1332 * @see org.eclipse.swt.widgets.Scrollable#getHorizontalBar()
1335 public ScrollBar
getHorizontalBar() {
1336 return fHorScrollBar
.getHorizontalBar();
1340 * Compute visibility of vertical/horizontal bar using given width/height and current visibility (i.e. is bar size are already in
1342 * @param forWidth width of foreground
1343 * @param forHeight height of foreground
1344 * @param currHorVis The current visibility state of horizontal scroll bar
1345 * @param currVertvis The current visibility state of vertical scroll bar
1346 * @return <code>true</code> if visibility changed else <code>false</code>
1348 public int computeBarVisibility(int forWidth
, int forHeight
, boolean currHorVis
, boolean currVertvis
) {
1350 int localForWidth
= forWidth
;
1352 switch (fVertScrollbarMode
) {
1359 if (getContentsHeight() > forHeight
) {
1361 // v bar size is already in for_width.
1362 if (!currVertvis
) {// (curr_vis&0x01)==0)
1363 localForWidth
-= getVerticalBarWidth();
1371 switch (fHorScrollbarMode
) {
1378 if (getContentsWidth() > localForWidth
) {
1380 // h bar is not in for_height
1381 if ((!currHorVis
) && (getContentsHeight() > (forHeight
- getHorizontalBarHeight()))) {// (curr_vis&0x02)==0 )
1393 * Setup scroll bars visibility.
1395 * @return True if one of visibility changed.
1397 protected boolean updateScrollBarVisiblity() {
1398 boolean change
= false;
1400 boolean currVertVis
= fVertScrollBar
.getVisible();
1401 boolean currHorVis
= fHorScrollBar
.getVisible();
1402 int barNewVis
= computeBarVisibility(getVisibleWidth(), getVisibleHeight(), currHorVis
, currVertVis
);
1403 boolean newVertVis
= (barNewVis
& VBAR
) != 0;
1404 boolean newHorVis
= (barNewVis
& HBAR
) != 0;
1405 if (currVertVis ^ newVertVis
) { // vertsb_.getVisible() )
1406 fVertScrollBar
.setVisible(newVertVis
);
1409 if (currHorVis ^ newHorVis
) {
1410 fHorScrollBar
.setVisible(newHorVis
);
1414 // update corner control visibility:
1415 if (fCornerControl
!= null && change
) {
1416 boolean vis
= newVertVis
|| newHorVis
;
1417 if (vis ^ fCornerControl
.getVisible()) {
1418 fCornerControl
.setVisible(vis
);
1419 change
= true; // but must be already the case
1426 * Setup scroll bar using contents, visible and scroll bar mode properties.
1428 protected void updateScrollBarsValues() {
1429 /* update vertical scrollbar */
1430 ScrollBar b
= getVerticalBar();
1433 b
.setMaximum(getContentsHeight());
1434 b
.setThumb(getVisibleHeight());
1435 b
.setPageIncrement(getVisibleHeight());
1436 b
.setIncrement(fVertScrollbarIncrement
);
1437 b
.setSelection(getContentsY());
1440 // update "hidden" vertical bar too
1441 b
= fViewControl
.getVerticalBar();
1444 b
.setMaximum(getContentsHeight());
1445 b
.setThumb(getVisibleHeight());
1446 b
.setPageIncrement(getVisibleHeight());
1447 b
.setIncrement(fVertScrollbarIncrement
);
1448 b
.setSelection(getContentsY());
1451 /* update horizontal scrollbar */
1452 b
= getHorizontalBar();
1455 b
.setMaximum(getContentsWidth());
1456 b
.setThumb(getVisibleWidth());
1457 b
.setSelection(getContentsX());
1458 b
.setPageIncrement(getVisibleWidth());
1459 b
.setIncrement(fHorScrollbarIncrement
);
1461 // update "hidden" horizontal bar too
1462 b
= fViewControl
.getHorizontalBar();
1465 b
.setMaximum(getContentsWidth());
1466 b
.setThumb(getVisibleWidth());
1467 b
.setSelection(getContentsX());
1468 b
.setPageIncrement(getVisibleWidth());
1469 b
.setIncrement(fHorScrollbarIncrement
);
1474 * Change the control used in the bottom right corner (between two scrollbar), if control is null reset previous
1475 * corner control. This control is visible only if at least one scrollbar is visible. Given control will be disposed
1476 * by ScrollView, at dispose() time, at next setCornetControl() call or when calling setOverviewEnabled(). Pay
1477 * attention calling this reset overview feature until setOverviewEnabled(true) if called.
1478 * @param control The control for the overview
1480 public void setCornerControl(Control control
) {
1481 if (fCornerControl
!= null) {
1482 fCornerControl
.dispose();
1484 fCornerControl
= control
;
1485 if (fCornerControl
!= null) {
1486 ScrollBar vb
= getVerticalBar();
1487 ScrollBar hb
= getHorizontalBar();
1488 boolean vis
= vb
.getVisible() || hb
.getVisible();
1489 fCornerControl
.setVisible(vis
);
1494 * Transform (x,y) point in widget coordinates to contents coordinates.
1496 * @param x The x widget coordinate.
1497 * @param y The y widget coordinate.
1498 * @return org.eclipse.swt.graphics.Point with content coordinates.
1500 public final Point
viewToContents(int x
, int y
) {
1501 return new Point(viewToContentsX(x
), viewToContentsY(y
));
1505 * Transform x in widget coordinates to contents coordinates
1507 * @param x The y widget coordinate.
1508 * @return the x content coordinate.
1510 public int viewToContentsX(int x
) {
1511 return fContentsX
+ x
;
1515 * Transform y in widget coordinates to contents coordinates
1517 * @param y The y widget coordinate.
1518 * @return the y content coordinate.
1520 public int viewToContentsY(int y
) {
1521 return fContentsY
+ y
;
1525 * Transform (x,y) point from contents coordinates, to widget coordinates.
1527 * @param x The x content coordinate.
1528 * @param y The y content coordinate.
1529 * @return coordinates widget area as.
1531 public final Point
contentsToView(int x
, int y
) {
1532 return new Point(contentsToViewX(x
), contentsToViewY(y
));
1536 * Transform X axis coordinates from contents to widgets.
1538 * @param x contents coordinate to transform.
1539 * @return x coordinate in widget area
1541 public int contentsToViewX(int x
) {
1542 return x
- fContentsX
;
1546 * Transform Y axis coordinates from contents to widgets.
1548 * @param y contents coordinate to transform
1549 * @return y coordinate in widget area
1551 public int contentsToViewY(int y
) {
1552 return y
- fContentsY
;
1556 * Return the visible height of scroll view, might be > contentsHeight
1558 * @return the visible height of scroll view, might be > contentsHeight()
1560 public int getVisibleHeight() {
1561 return fViewControl
.getClientArea().height
;
1565 * Return int the visible width of scroll view, might be > contentsWidth().
1567 * @return int the visible width of scroll view, might be > contentsWidth()
1569 public int getVisibleWidth() {
1570 return fViewControl
.getClientArea().width
;
1574 * Add support for arrow key, scroll the ... scroll view. But you can
1575 * redefine this method for your convenience.
1580 protected void keyPressedEvent(KeyEvent event
) {
1581 switch (event
.keyCode
) {
1583 scrollBy(0, -getVisibleHeight());
1585 case SWT
.ARROW_DOWN
:
1586 scrollBy(0, +getVisibleHeight());
1588 case SWT
.ARROW_LEFT
:
1589 scrollBy(-getVisibleWidth(), 0);
1591 case SWT
.ARROW_RIGHT
:
1592 scrollBy(+getVisibleWidth(), 0);
1600 * Redefine this method at your convenience
1602 * @param event The key event.
1604 protected void keyReleasedEvent(KeyEvent event
) {
1608 * Returns vertical bar width, even if bar isn't visible.
1610 * @return vertical bar width, even if bar isn't visible
1612 public int getVerticalBarWidth() {
1613 // include vertical bar width and trimming of scrollable used
1614 int bw
= fVertScrollBar
.computeTrim(0, 0, 0, 0).width
;
1619 * Returns horizontal bar height even if bar isn't visible.
1621 * @return horizontal bar height even if bar isn't visible
1623 public int getHorizontalBarHeight() {
1624 // include horiz. bar height and trimming of scrollable used
1625 int bh
= fHorScrollBar
.computeTrim(0, 0, 0, 0).height
;
1626 // +1 because win32 H.bar need 1 pixel canvas size to appear ! (strange no ?)
1632 * @see org.eclipse.swt.widgets.Scrollable#computeTrim(int, int, int, int)
1635 public Rectangle
computeTrim(int x
, int y
, int w
, int h
) {
1636 Rectangle r
= new Rectangle(x
, y
, w
, h
);
1637 int bar_vis
= computeBarVisibility(w
, h
, false, false);
1638 if ((bar_vis
& VBAR
) != 0) {
1639 r
.width
+= getVerticalBarWidth();
1641 if ((bar_vis
& HBAR
) != 0) {
1642 r
.height
+= getHorizontalBarHeight();
1648 * Internal layout for ScrollView, handle scrollbars, drawzone and corner control
1650 protected class SVLayout
extends Layout
{
1656 * The do-it-not flag
1658 boolean dontLayout
= false;
1662 * @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite, int, int, boolean)
1665 protected Point
computeSize(Composite composite
, int wHint
, int hHint
, boolean flushCache
) {
1666 Point p
= new Point(250, 250);
1667 if (fContentsWidth
< p
.x
) {
1668 p
.x
= fContentsWidth
;
1670 if (fContentsHeight
< p
.y
) {
1671 p
.y
= fContentsHeight
;
1678 * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite, boolean)
1681 protected void layout(Composite composite
, boolean flushCache
) {
1690 Point cs
= composite
.getSize();
1691 int bar_vis
= computeBarVisibility(cs
.x
, cs
.y
, false, false);
1692 boolean vb_vis
= (bar_vis
& VBAR
) != 0;
1693 boolean hb_vis
= (bar_vis
& HBAR
) != 0;
1694 fVertScrollBar
.setVisible(vb_vis
);
1695 fHorScrollBar
.setVisible(hb_vis
);
1696 int vbw
= getVerticalBarWidth();
1697 int hbh
= getHorizontalBarHeight();
1698 int wb
= vb_vis ? vbw
: 0;
1699 int hb
= hb_vis ? hbh
: 0;
1700 int cww
= 0, cwh
= 0;
1702 if (fCornerControl
!= null && (vb_vis
|| hb_vis
)) { // corner_control_.getVisible())
1703 fCornerControl
.setVisible(true);
1712 } else if (vb_vis
&& hb_vis
) {
1713 if (fCornerControl
!= null) {
1714 fCornerControl
.setVisible(false);
1719 if (vb_vis
|| hb_vis
) {
1720 updateScrollBarsValues();
1723 int vw
= cs
.x
- (vb_vis ? vbw
: 0);
1724 int vh
= cs
.y
- (hb_vis ? hbh
: 0);
1725 int vbx
= cs
.x
- wb
;
1726 int hby
= cs
.y
- hb
;
1728 fViewControl
.setBounds(0, 0, vw
, vh
);
1731 fVertScrollBar
.setBounds(vbx
, 0, wb
, cs
.y
- cwh
);
1734 fHorScrollBar
.setBounds(0, hby
, cs
.x
- cww
, hb
);
1736 if (fCornerControl
!= null && fCornerControl
.getVisible()) {
1737 fCornerControl
.setBounds(vbx
, hby
, vbw
, hbh
);
1739 updateScrollBarsValues();
1748 // static must take place here... cursor is created once.
1749 volatile static Cursor fOverviewCursor
;
1751 /** Support for click-and-see overview shell on this ScrollView */
1752 protected class Overview
{
1755 * factor for X from real and overview sizes, for mouse move speed.
1757 protected float fOverviewFactorX
;
1760 * factor for Y from real and overview sizes, for mouse move speed.
1762 protected float fOverviewFactorY
;
1764 * shell use to show overview
1766 protected Shell fOverview
;
1768 * save mouse X cursor location for disappear();
1770 protected int fSaveCursorX
;
1772 * save mouse Y cursor location for disappear();
1774 protected int fSaveCursorY
;
1777 * Apply overview support on a control. Replace existing corner_widget
1780 * The control to use
1782 public void useControl(Control control
) {
1783 final Point pos
= control
.getLocation();
1784 control
.addMouseListener(new MouseListener() {
1786 public void mouseDoubleClick(MouseEvent e
) {
1790 public void mouseDown(MouseEvent e
) {
1791 overviewAppear(e
.x
, e
.y
);
1795 public void mouseUp(MouseEvent e
) {
1796 overviewDisappear();
1800 control
.addFocusListener(new FocusListener() {
1803 public void focusGained(FocusEvent e
) {
1807 public void focusLost(FocusEvent e
) {
1808 if (overviewing()) {
1809 overviewDisappear(false);
1814 control
.addKeyListener(new KeyListener() {
1817 public void keyPressed(KeyEvent event
) {
1818 if (event
.keyCode
== 32 && !overviewing()) {
1819 overviewAppear(pos
.x
, pos
.y
);
1820 } else if (event
.keyCode
== 32) {
1821 overviewDisappear();
1823 if (event
.keyCode
== SWT
.ARROW_DOWN
) {
1824 overviewMove(0, 1, event
);
1827 if (event
.keyCode
== SWT
.ARROW_UP
) {
1828 overviewMove(0, -1, event
);
1831 if (event
.keyCode
== SWT
.ARROW_RIGHT
) {
1832 overviewMove(1, 0, event
);
1835 if (event
.keyCode
== SWT
.ARROW_LEFT
) {
1836 overviewMove(-1, 0, event
);
1841 public void keyReleased(KeyEvent e
) {
1844 control
.addMouseMoveListener(new MouseMoveListener() {
1845 private int refReshCount
= 0;
1847 public void mouseMove(MouseEvent event
) {
1848 if (overviewing()) {
1849 // Slow down the refresh
1850 if (refReshCount
% 4 == 0) {
1851 overviewMove(event
);
1860 * Dispose controls of overview
1862 public void dispose() {
1863 if (fOverview
!= null) {
1864 fOverview
.dispose();
1869 * @return true if overview is currently on screen
1871 protected boolean overviewing() {
1872 return (fOverview
!= null && fOverview
.isVisible());
1876 * Process overview appear
1883 protected void overviewAppear(int mx
, int my
) {
1884 if (fOverview
== null) {
1885 fOverview
= new Shell(getShell(), SWT
.ON_TOP
| SWT
.NO_BACKGROUND
);
1886 fOverview
.addPaintListener(new PaintListener() {
1888 public void paintControl(PaintEvent e
) {
1889 drawOverview(e
.gc
, fOverview
.getClientArea());
1893 // always the same..
1894 // overview.setBackground( viewcontrol_.getBackground() );
1895 fOverview
.setForeground(fViewControl
.getForeground());
1897 // get location of shell (in screeen coordinates)
1898 Point p
= toGlobalCoordinates(fCornerControl
, 0, 0);
1902 w
= h
= fOverviewSize
;
1903 Rectangle scr
= getDisplay().getBounds();
1904 Point ccs
= fCornerControl
.getSize();
1906 if (fContentsWidth
> fContentsHeight
) {
1907 float ratio
= fContentsHeight
/ (float) fContentsWidth
;
1908 h
= (int) (w
* ratio
);
1911 } else if (h
>= scr
.height
/ 2) {
1915 float ratio
= fContentsWidth
/ (float) fContentsHeight
;
1916 w
= (int) (h
* ratio
);
1919 } else if (w
>= scr
.width
/ 2) {
1923 fOverviewFactorX
= fContentsWidth
/ (float) w
;
1924 fOverviewFactorY
= fContentsHeight
/ (float) h
;
1926 // no contents size set ?
1927 catch (java
.lang
.ArithmeticException e
) {
1930 // try pop-up on button, extending to bottom right,
1931 // if outside screen, extend pop-up to top left
1932 // if( x+w > scr.width ) x = scr.width-w; //x += corner_control_.getSize().x-w;
1933 // if( y+h > scr.height ) y = scr.height-h;//y += corner_control_.getSize().y-h;
1942 fOverview
.setBounds(x
, y
, w
, h
);
1943 fOverview
.setVisible(true);
1945 // mouse cursor disappear, so set invisible mouse cursor ...
1946 if (fOverviewCursor
== null) {
1947 RGB rgb
[] = { new RGB(0, 0, 0), new RGB(255, 0, 0) };
1948 PaletteData palette
= new PaletteData(rgb
);
1950 byte src
[] = new byte[s
* s
];
1951 byte msk
[] = new byte[s
* s
];
1952 for (int i
= 0; i
< s
* s
; ++i
) {
1953 src
[i
] = (byte) 0xFF;
1955 ImageData i_src
= new ImageData(s
, s
, 1, palette
, 1, src
);
1956 ImageData i_msk
= new ImageData(s
, s
, 1, palette
, 1, msk
);
1957 fOverviewCursor
= new Cursor(null, i_src
, i_msk
, 0, 0);
1959 fCornerControl
.setCursor(fOverviewCursor
);
1960 // convert to global coordinates
1961 p
= toGlobalCoordinates(fCornerControl
, mx
, my
);
1965 Rectangle r
= fOverview
.getClientArea();
1966 int cx
= (int) (r
.width
* fContentsX
/ (float) fContentsWidth
);
1967 int cy
= (int) (r
.height
* fContentsY
/ (float) fContentsHeight
);
1969 // cx,cy to display's global coordinates
1970 p
= toGlobalCoordinates(fOverview
.getParent(), cx
, cy
);
1974 * Process disappear of overview
1976 protected void overviewDisappear() {
1977 overviewDisappear(true);
1981 * Process disappear of overview
1982 * @param restoreCursorLoc A flag to restore cursor location
1984 protected void overviewDisappear(boolean restoreCursorLoc
) {
1985 if (fOverview
== null) {
1988 fOverview
.setVisible(false);
1989 fCornerControl
.setCursor(null);
1990 if (restoreCursorLoc
) {
1991 getDisplay().setCursorLocation(fSaveCursorX
, fSaveCursorY
);
1993 fOverview
.dispose();
1998 * Process mouse move in overview
1999 * @param event The mouse event
2001 protected void overviewMove(MouseEvent event
) {
2002 Point p
= toGlobalCoordinates(fCornerControl
, event
.x
, event
.y
);
2003 int dx
= p
.x
- fSaveCursorX
;
2004 int dy
= p
.y
- fSaveCursorY
;
2005 overviewMove(dx
, dy
, event
);
2009 * Process mouse move event when overviewing
2011 * @param dx The x coordinates delta
2012 * @param dy The y coordinates delta
2013 * @param event The typed event
2015 protected void overviewMove(int dx
, int dy
, TypedEvent event
) {
2016 boolean ctrl
= false;
2017 boolean shift
= false;
2019 if (event
instanceof MouseEvent
) {
2020 MouseEvent e
= (MouseEvent
) event
;
2021 getDisplay().setCursorLocation(fSaveCursorX
, fSaveCursorY
);
2022 ctrl
= (e
.stateMask
& SWT
.CONTROL
) != 0;
2023 shift
= (e
.stateMask
& SWT
.SHIFT
) != 0;
2024 } else if (event
instanceof KeyEvent
) {
2025 KeyEvent e
= (KeyEvent
) event
;
2026 ctrl
= (e
.stateMask
& SWT
.CONTROL
) != 0;
2027 shift
= (e
.stateMask
& SWT
.SHIFT
) != 0;
2030 int cx
= fContentsX
;
2031 int cy
= fContentsY
;
2032 float fx
= fOverviewFactorX
;
2033 float fy
= fOverviewFactorY
;
2035 if (ctrl
&& shift
) {
2036 if ((fx
* 0.25f
> 1) && (fy
* 0.25 > 1)) {
2049 scrollBy((int) (fx
* dx
), (int) (fy
* dy
));
2050 if (cx
!= fContentsX
|| cy
!= fContentsY
) {
2052 fOverview
.update(); // draw now !
2057 * Convert overview coordinates to global coordinates.
2060 * the control reference
2062 * The x coordinate to convert
2064 * The y coordinate to convert
2065 * @return The new converted Point
2067 protected Point
toGlobalCoordinates(Control loc
, int x
, int y
) {
2068 Point p
= new Point(x
, y
);
2069 for (Control c
= loc
; c
!= null; c
= c
.getParent()) {
2070 // control might have client area with 'decorations'
2071 int trim_x
= 0, trim_y
= 0;
2072 // other kind of widget with trimming ??
2073 if (c
instanceof Scrollable
) {
2074 Scrollable s
= (Scrollable
) c
;
2075 Rectangle rr
= s
.getClientArea();
2076 Rectangle tr
= s
.computeTrim(rr
.x
, rr
.y
, rr
.width
, rr
.height
);
2077 trim_x
= rr
.x
- tr
.x
;
2078 trim_y
= rr
.y
- tr
.y
;
2080 p
.x
+= c
.getLocation().x
+ trim_x
;
2081 p
.y
+= c
.getLocation().y
+ trim_y
;