1 /**********************************************************************
2 * Copyright (c) 2005, 2008 IBM Corporation and others.
3 * Copyright (c) 2011, 2012 Ericsson.
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
11 * IBM - Initial API and implementation
12 * Bernd Hufmann - Updated for TMF
13 **********************************************************************/
14 package org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
;
16 import java
.util
.Timer
;
17 import java
.util
.TimerTask
;
19 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.util
.SDMessages
;
20 import org
.eclipse
.swt
.SWT
;
21 import org
.eclipse
.swt
.events
.ControlListener
;
22 import org
.eclipse
.swt
.events
.FocusEvent
;
23 import org
.eclipse
.swt
.events
.FocusListener
;
24 import org
.eclipse
.swt
.events
.KeyEvent
;
25 import org
.eclipse
.swt
.events
.KeyListener
;
26 import org
.eclipse
.swt
.events
.MouseEvent
;
27 import org
.eclipse
.swt
.events
.MouseListener
;
28 import org
.eclipse
.swt
.events
.MouseMoveListener
;
29 import org
.eclipse
.swt
.events
.MouseTrackListener
;
30 import org
.eclipse
.swt
.events
.PaintEvent
;
31 import org
.eclipse
.swt
.events
.PaintListener
;
32 import org
.eclipse
.swt
.events
.SelectionEvent
;
33 import org
.eclipse
.swt
.events
.SelectionListener
;
34 import org
.eclipse
.swt
.events
.TypedEvent
;
35 import org
.eclipse
.swt
.graphics
.Color
;
36 import org
.eclipse
.swt
.graphics
.Cursor
;
37 import org
.eclipse
.swt
.graphics
.GC
;
38 import org
.eclipse
.swt
.graphics
.ImageData
;
39 import org
.eclipse
.swt
.graphics
.PaletteData
;
40 import org
.eclipse
.swt
.graphics
.Point
;
41 import org
.eclipse
.swt
.graphics
.RGB
;
42 import org
.eclipse
.swt
.graphics
.Rectangle
;
43 import org
.eclipse
.swt
.widgets
.Button
;
44 import org
.eclipse
.swt
.widgets
.Canvas
;
45 import org
.eclipse
.swt
.widgets
.Composite
;
46 import org
.eclipse
.swt
.widgets
.Control
;
47 import org
.eclipse
.swt
.widgets
.Display
;
48 import org
.eclipse
.swt
.widgets
.Layout
;
49 import org
.eclipse
.swt
.widgets
.ScrollBar
;
50 import org
.eclipse
.swt
.widgets
.Scrollable
;
51 import org
.eclipse
.swt
.widgets
.Shell
;
54 * ScrollView widget provides a scrolling area with on-demand scroll bars.
55 * Overview scrollable panel can be used (@see setOverviewEnabled()).
57 * @author Eric Miravete
60 public class ScrollView
extends Composite
{
62 // ------------------------------------------------------------------------
64 // ------------------------------------------------------------------------
66 // Value for scroll bar mode, default is AUTO
68 * Scroll bar mode AUTO
70 public static final int AUTO
= 0;
72 * Scroll bar mode ALWAYS_ON
74 public static final int ALWAYS_ON
= 1;
76 * Scroll bar mode ALWAYS_OFF
78 public static final int ALWAYS_OFF
= 2;
80 * Bit mask for visible vertical scroll bar
82 public static final int VBAR
= 0x01;
84 * Bit mask for visible horizontal scroll bar
86 public static final int HBAR
= 0x02;
88 * Value of the contents_height_ property.
90 protected int contents_height_
= 0;
92 * Value of the contents_width_ property.
94 protected int contents_width_
= 0;
96 * Value of the contents_x_ property
98 protected int contents_x_
= 0;
100 * Value of the contents_y_ property
102 protected int contents_y_
= 0;
104 * Scroll bar mode of vertical scroll bar.
106 protected int h_scrollbar_mode_
= AUTO
;
108 * Scroll bar mode of horizontal scroll bar.
110 protected int v_scrollbar_mode_
= AUTO
;
112 * Increment for the horizontal scroll bar.
114 protected int h_scrollbar_increment_
= 10;
116 * Increment for the vertical scroll bar.
118 protected int v_scrollbar_increment_
= 10;
120 * Flag whether auto scroll is enabled or not.
122 protected boolean auto_scroll_enabled_
= true;
124 * Value of the auto scroll period.
126 protected int auto_scroll_period_
= 75;
129 * The local paint listener reference.
131 protected PaintListener localPaintListener
= null;
133 * The local mouse move listener reference.
135 protected MouseMoveListener localMouseMoveListener
= null;
137 * The local mouse listener reference.
139 protected MouseListener localMouseListener
= null;
141 * The local control listener reference.
143 protected ControlListener localControlListener
= null;
145 * The local key listener reference.
147 protected KeyListener localKeyListener
= null;
148 // Canvas for vertical/horizontal Scroll Bar only ... because new ScrollBar() does works.
150 * Canvas for horizontal scroll bar.
152 protected Canvas horzsb_
;
154 * Canvas for vertical scroll bar.
156 protected Canvas vertsb_
;
158 * Canvas for the view control.
160 protected Canvas viewcontrol_
;
162 * Control used in the bottom right corner @see setCornerControl() and @see setOverviewEnabled(true)
164 protected Control corner_control_
;
166 * Size of overview widget.
168 protected int overview_size_
= 100; // default size for overview
170 // ------------------------------------------------------------------------
172 // ------------------------------------------------------------------------
175 * Create a ScrollView, child of composite c. Both scroll bar have the mode AUTO. Auto scroll feature is enabled
176 * using a delay of 250ms. Overview feature is not enabled by default (use setOverviewEnabled()).
178 * @param c The parent composite
179 * @param style The SWT style bits @see SWT
181 public ScrollView(Composite c
, int style
) {
182 this(c
, style
, true);
186 * Create a ScrollView, child of composite c. Both scroll bar have the mode AUTO. Auto scroll feature is enabled
187 * using a delay of 250ms. Overview feature is not enabled by default (use setOverviewEnabled()).
189 * @param c The parent composite.
190 * @param style The SWT style bits @see SWT
191 * @param mouseWheel Flag to force scrollView to handles mouse wheel
193 public ScrollView(Composite c
, int style
, boolean mouseWheel
) {
194 super(c
, SWT
.NONE
); // style&(~(SWT.H_SCROLL|SWT.V_SCROLL)));
196 horzsb_
= new Canvas(this, SWT
.H_SCROLL
);
198 // force scroll bar to get mouse wheel, those scrollbar will be hidden
199 viewcontrol_
= new Canvas(this, style
| SWT
.H_SCROLL
| SWT
.V_SCROLL
);
201 viewcontrol_
= new Canvas(this, style
);
203 viewcontrol_
.setBackground(getBackground());
204 // hide scroll bar as their are replaced by vertsb_ and horzsb_.
206 viewcontrol_
.getVerticalBar().setVisible(false);
207 viewcontrol_
.getHorizontalBar().setVisible(false);
209 vertsb_
= new Canvas(this, SWT
.V_SCROLL
);
210 // make vertsb_ able to receive mouse wheel
211 // doesnot help as we can't set a MouseListener on vertsb_.getVerticalBar()
212 // to set focus on viewcontrol_
213 // vertsb_.addKeyListener( new KeyAdapter() {});
215 setLayout(new SVLayout());
217 localPaintListener
= new PaintListener() {
219 public void paintControl(PaintEvent event
) {
220 // use clipping, to reduce cost of paint.
221 Rectangle r
= event
.gc
.getClipping();
222 int cx
= viewToContentsX(r
.x
);
223 int cy
= viewToContentsY(r
.y
);
224 drawContents(event
.gc
, cx
, cy
, r
.width
, r
.height
);
227 viewcontrol_
.addPaintListener(localPaintListener
);
229 localMouseMoveListener
= new MouseMoveListener() {
231 public void mouseMove(MouseEvent e
) {
232 int ox
= e
.x
, oy
= e
.y
;
233 e
.x
= viewToContentsX(e
.x
);
234 e
.y
= viewToContentsY(e
.y
);
235 contentsMouseMoveEvent(e
);
241 viewcontrol_
.addMouseMoveListener(localMouseMoveListener
);
243 MouseTrackListener localMouseTrackListener
= new MouseTrackListener() {
245 public void mouseEnter(MouseEvent e
) {
246 int ox
= e
.x
, oy
= e
.y
;
247 e
.x
= viewToContentsX(e
.x
);
248 e
.y
= viewToContentsY(e
.y
);
249 contentsMouseEnter(e
);
255 public void mouseHover(MouseEvent e
) {
256 int ox
= e
.x
, oy
= e
.y
;
257 e
.x
= viewToContentsX(e
.x
);
258 e
.y
= viewToContentsY(e
.y
);
259 contentsMouseHover(e
);
265 public void mouseExit(MouseEvent e
) {
266 int ox
= e
.x
, oy
= e
.y
;
267 e
.x
= viewToContentsX(e
.x
);
268 e
.y
= viewToContentsY(e
.y
);
269 contentsMouseExit(e
);
276 viewcontrol_
.addMouseTrackListener(localMouseTrackListener
);
278 localMouseListener
= new MouseListener() {
280 public void mouseDoubleClick(MouseEvent e
) {
281 int ox
= e
.x
, oy
= e
.y
;
282 e
.x
= viewToContentsX(e
.x
);
283 e
.y
= viewToContentsY(e
.y
);
284 contentsMouseDoubleClickEvent(e
);
290 public void mouseDown(MouseEvent e
) {
291 int ox
= e
.x
, oy
= e
.y
;
292 e
.x
= mouse_down_x_
= viewToContentsX(e
.x
);
293 e
.y
= mouse_down_y_
= viewToContentsY(e
.y
);
294 contentsMouseDownEvent(e
);
300 public void mouseUp(MouseEvent e
) {
301 int ox
= e
.x
, oy
= e
.y
;
302 e
.x
= viewToContentsX(e
.x
);
303 e
.y
= viewToContentsY(e
.y
);
304 contentsMouseUpEvent(e
);
307 // here because class extenting me can catch mouse Up and want to scroll...
308 mouse_down_x_
= mouse_down_y_
= -1;
311 viewcontrol_
.addMouseListener(localMouseListener
);
313 localKeyListener
= new KeyListener() {
315 public void keyPressed(KeyEvent e
) {
320 public void keyReleased(KeyEvent e
) {
325 viewcontrol_
.addKeyListener(localKeyListener
);
327 getVerticalBar().addSelectionListener(new SelectionListener() {
329 public void widgetSelected(SelectionEvent e
) {
330 setContentsPos(contents_x_
, getVerticalBar().getSelection());
331 // need to change "hidden" vertical bar value ?
332 // force focus on viewcontrol_ so we got future mouse wheel's scroll events
333 if (!viewcontrol_
.isFocusControl()) {
334 viewcontrol_
.setFocus();
339 public void widgetDefaultSelected(SelectionEvent e
) {
343 if (viewcontrol_
.getVerticalBar() != null)
344 // add viewcontrol hidden scrollbar listener to get mouse wheel ...
345 viewcontrol_
.getVerticalBar().addSelectionListener(new SelectionListener() {
347 public void widgetSelected(SelectionEvent e
) {
348 ScrollBar b
= viewcontrol_
.getVerticalBar();
349 setContentsPos(contents_x_
, b
.getSelection());
350 // change "real" vertical bar selection too
351 getVerticalBar().setSelection(b
.getSelection());
355 public void widgetDefaultSelected(SelectionEvent e
) {
358 getHorizontalBar().addSelectionListener(new SelectionListener() {
360 public void widgetSelected(SelectionEvent e
) {
361 setContentsPos(getHorizontalBar().getSelection(), contents_y_
);
362 // need to change "real" horizontal bar too ?
363 // force focus on viewcontrol_ so we got future mouse wheel's scroll events
364 if (!viewcontrol_
.isFocusControl()) {
365 viewcontrol_
.setFocus();
370 public void widgetDefaultSelected(SelectionEvent e
) {
373 if (viewcontrol_
.getHorizontalBar() != null)
374 viewcontrol_
.getHorizontalBar().addSelectionListener(new SelectionListener() {
376 public void widgetSelected(SelectionEvent e
) {
377 ScrollBar b
= viewcontrol_
.getHorizontalBar();
378 setContentsPos(b
.getSelection(), contents_y_
);
379 // change "real" vertical bar selection too
380 getHorizontalBar().setSelection(b
.getSelection());
384 public void widgetDefaultSelected(SelectionEvent e
) {
389 // ------------------------------------------------------------------------
391 // ------------------------------------------------------------------------
395 * @see org.eclipse.swt.widgets.Composite#setFocus()
398 public boolean setFocus() {
399 return viewcontrol_
.forceFocus();
404 * @see org.eclipse.swt.widgets.Control#setCursor(org.eclipse.swt.graphics.Cursor)
407 public void setCursor(Cursor cursor
) {
408 viewcontrol_
.setCursor(cursor
);
412 * Dispose controls used in scroll view
415 * @see org.eclipse.swt.widgets.Widget#dispose()
418 public void dispose() {
419 if (auto_scroll_
!= null) {
420 auto_scroll_
.cancel();
423 if (viewcontrol_
!= null) {
424 viewcontrol_
.dispose();
427 if (vertsb_
!= null) {
431 if (horzsb_
!= null) {
435 if (corner_control_
!= null) {
436 Object data
= corner_control_
.getData();
437 if (data
instanceof Overview
) {
438 ((Overview
) data
).dispose();
440 corner_control_
.dispose();
441 corner_control_
= null;
448 * @see org.eclipse.swt.widgets.Composite#getClientArea()
451 public Rectangle
getClientArea() {
452 return viewcontrol_
.getClientArea();
457 * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color)
460 public void setBackground(Color c
) {
461 super.setBackground(c
);
462 viewcontrol_
.setBackground(c
);
467 * @see org.eclipse.swt.widgets.Control#setToolTipText(java.lang.String)
470 public void setToolTipText(String text
) {
471 viewcontrol_
.setToolTipText(text
);
475 * Draw overview area, @see setOverviewEnabled. By default draw a rectangle corresponding to the visible area of
476 * scroll view. You can redefine this method to draw the contents as drawContents does... ...in an other magnify
479 * @param gc GC to used to draw.
480 * @param r Rectangle corresponding to the client area of overview.
482 protected void drawOverview(GC gc
, Rectangle r
) {
483 int x
= (int) (r
.width
* contents_x_
/ (float) contents_width_
);
484 int y
= (int) (r
.height
* contents_y_
/ (float) contents_height_
);
485 int vw
= getVisibleWidth();
486 int vh
= getVisibleHeight();
488 if (contents_width_
> vw
) {
489 w
= (int) (r
.width
* vw
/ (float) contents_width_
);
491 int h
= r
.height
- 1;
492 if (contents_height_
> vh
) {
493 h
= (int) (r
.height
* vh
/ (float) contents_height_
);
496 gc
.setForeground(getForeground());
497 // too small rectangle ?
498 if (w
< 5 || h
< 5) {
500 gc
.drawLine(x
, 0, x
, r
.height
);
501 gc
.drawLine(0, y
, r
.width
, y
);
503 gc
.drawRectangle(x
, y
, w
, h
);
508 * Remove the local Listener and add the new listener.
510 * @param nlistener the new listener
512 public void replaceControlListener(ControlListener nlistener
) {
513 if (localControlListener
!= null) {
514 removeControlListener(localControlListener
);
515 localControlListener
= null;
517 addControlListener(nlistener
);
521 * Remove the local Listener and add the new listener.
523 * @param nlistener the new listener
525 public void replaceKeyListener(KeyListener nlistener
) {
526 if (localKeyListener
!= null) {
527 removeKeyListener(localKeyListener
);
528 localKeyListener
= null;
530 addKeyListener(nlistener
);
534 * Remove the local Listener and add the new listener.
536 * @param nlistener the new listener
538 public void replaceMouseListener(MouseListener nlistener
) {
539 if (localMouseListener
!= null) {
540 removeMouseListener(localMouseListener
);
541 localMouseListener
= null;
543 viewcontrol_
.addMouseListener(nlistener
);
547 * Remove the local Listener and add the new listener.
549 * @param nlistener the new listener
551 public void replaceMouseMoveListener(MouseMoveListener nlistener
) {
552 if (localMouseMoveListener
!= null) {
553 removeMouseMoveListener(localMouseMoveListener
);
554 localMouseMoveListener
= null;
556 viewcontrol_
.addMouseMoveListener(nlistener
);
560 * Remove the local Listener and add the new listener.
562 * @param nlistener the new listener
564 public void replacePaintListener(PaintListener nlistener
) {
565 if (localPaintListener
!= null) {
566 removePaintListener(localPaintListener
);
567 localPaintListener
= null;
569 viewcontrol_
.addPaintListener(nlistener
);
573 * Access method for the contentsHeight property.
575 * @return the current value of the contentsHeight property
577 public int getContentsHeight() {
578 return contents_height_
;
582 * Access method for the contentsWidth property.
584 * @return the current value of the contentsWidth property
586 public int getContentsWidth() {
587 return contents_width_
;
591 * Access method for the contentsX property.
593 * @return the current value of the contentsX property
595 public int getContentsX() {
600 * Access method for the contentsY property.
602 * @return the current value of the contentsY property
604 public int getContentsY() {
609 * Determines if the dragAutoScroll property is true.
611 * @return <code>true<code> if the dragAutoScroll property is true
613 public boolean getDragAutoScroll() {
614 return auto_scroll_enabled_
;
618 * Sets the value of the dragAutoScroll property.
620 * @param aDragAutoScroll the new value of the dragAutoScroll property
622 public void setDragAutoScroll(boolean aDragAutoScroll
) {
623 auto_scroll_enabled_
= aDragAutoScroll
;
624 if (!auto_scroll_enabled_
&& (auto_scroll_
!= null)) {
625 auto_scroll_
.cancel();
631 * Change delay (in millisec) used for auto scroll feature.
633 * @param _period new period between to auto scroll
635 public void setDragAutoScrollPeriod(int _period
) {
636 auto_scroll_period_
= Math
.max(0, _period
);
640 * Return auto scroll period.
642 public int getDragAutoScrollPeriod() {
643 return auto_scroll_period_
;
647 * Access method for the hScrollBarMode property.
649 * @return the current value of the hScrollBarMode property
651 public int getHScrollBarMode() {
652 return h_scrollbar_mode_
;
656 * Sets the value of the hScrollBarMode property.
658 * @param aHScrollBarMode the new value of the hScrollBarMode property
660 public void setHScrollBarMode(int aHScrollBarMode
) {
661 h_scrollbar_mode_
= aHScrollBarMode
;
665 * Access method for the vScrollBarMode property.
667 * @return the current value of the vScrollBarMode property
669 public int getVScrollBarMode() {
670 return v_scrollbar_mode_
;
674 * Sets the value of the vScrollBarMode property.
676 * @param aVScrollBarMode the new value of the vScrollBarMode property
678 public void setVScrollBarMode(int aVScrollBarMode
) {
679 v_scrollbar_mode_
= aVScrollBarMode
;
683 * Return horizontal scroll bar increment, default:1
685 public int getHScrollBarIncrement() {
686 return h_scrollbar_increment_
;
690 * Return vertical scroll bar increment, default:1
692 public int getVScrollBarIncrement() {
693 return v_scrollbar_increment_
;
697 * Change horizontal scroll bar increment, minimum:1. Page increment is always set to visible width.
699 public void setHScrollBarIncrement(int _inc
) {
700 h_scrollbar_increment_
= Math
.max(1, _inc
);
704 * Change vertical scroll bar increment, minimum:1. Page increment is always set to visible height.
706 public void setVScrollBarIncrement(int _inc
) {
707 v_scrollbar_increment_
= Math
.max(1, _inc
);
711 * Enable or disable overview feature. Enabling overview, dispose and replace existing corner control by a button.
712 * Clicking in it open overview, move mouse cursor holding button to move scroll view and release button to hide
713 * overview. Tip: hold control and/or shift key while moving mouse when overview is open made fine scroll.
715 * @param _b true to engage overview feature
717 public void setOverviewEnabled(boolean _b
) {
718 if (getOverviewEnabled() == _b
) {
724 Button b
= new Button(this, SWT
.NONE
);
725 b
.setText("+"); //$NON-NLS-1$
726 Overview ovr
= new Overview();
730 b
.setToolTipText(SDMessages
._78
);
732 setCornerControl(cc
);
736 * Change overview size (at ratio 1:1), default is 100
738 public void setOverviewSize(int _size
) {
739 overview_size_
= Math
.abs(_size
);
743 * Returns whether the overview is enabled or not.
745 * @return true is overview feature is enabled
747 public boolean getOverviewEnabled() {
748 if (corner_control_
instanceof Button
) {
749 Object data
= ((Button
) corner_control_
).getData();
751 if (data
instanceof Overview
) {
759 * Returns the overview size at ratio 1:1.
761 * @return current overview size at ratio 1:1
763 public int getOverviewSize() {
764 return overview_size_
;
768 * Returns control used to display view (might not be this object). Use this control to add/remove listener on the
771 * @return control used to display view (might not be this object).
773 public Control
getViewControl() {
778 * Called when the mouse enter the ScrollView area
782 protected void contentsMouseExit(MouseEvent e
) {
786 * Called when the mouse enter the ScrollView area after and system defined time
790 protected void contentsMouseHover(MouseEvent e
) {
794 * Called when the mouse enter the ScrollView area
798 protected void contentsMouseEnter(MouseEvent e
) {
802 * Called when user double on contents area.
806 protected void contentsMouseDoubleClickEvent(MouseEvent e
) {
810 * Called when mouse is on contents area and button is pressed.
814 protected void contentsMouseDownEvent(MouseEvent e
) {
819 /** where mouse down appear on contents area */
820 protected int mouse_down_x_
= -1, mouse_down_y_
= -1;
822 /** TimerTask for auto scroll feature. */
823 protected static class AutoScroll
extends TimerTask
{
825 public ScrollView sv_
;
827 public AutoScroll(ScrollView _sv
, int _dx
, int _dy
) {
835 Display
.getDefault().asyncExec(new Runnable() {
838 sv_
.scrollBy(dx_
, dy_
);
844 /** Timer for auto_scroll feature */
845 protected AutoScroll auto_scroll_
= null;
846 /** TimerTask for auto_scroll feature !=null when auto scroll is running */
847 protected Timer auto_scroll_timer_
= null;
850 * Called when mouse is on contents area and mode.
854 protected void contentsMouseMoveEvent(MouseEvent _event
) {
855 if ((_event
.stateMask
& SWT
.BUTTON_MASK
) != 0) {
856 if (!auto_scroll_enabled_
) {
857 scrollBy(-(_event
.x
- mouse_down_x_
), -(_event
.y
- mouse_down_y_
));
863 int v_right
= getContentsX() + getVisibleWidth();
864 int v_bottom
= getContentsY() + getVisibleHeight();
867 if (_event
.x
< getContentsX()) {
868 sx
= (getContentsX() - _event
.x
);
869 mouse_down_x_
= getContentsX();
870 } else if (_event
.x
> v_right
) {
871 sx
= -_event
.x
+ v_right
;
872 mouse_down_x_
= v_right
;
874 if (_event
.y
< getContentsY()) {
875 sy
= (getContentsY() - _event
.y
);
876 mouse_down_y_
= getContentsY();
877 } else if (_event
.y
> v_bottom
) {
878 sy
= -_event
.y
+ v_bottom
;
879 mouse_down_y_
= v_bottom
;
882 if (sx
!= 0 || sy
!= 0) {
883 // start auto scroll...
884 if (auto_scroll_
== null) {
885 if (auto_scroll_timer_
== null) {
886 auto_scroll_timer_
= new Timer(true);
888 auto_scroll_
= new AutoScroll(this, sx
, sy
);
889 auto_scroll_timer_
.schedule(auto_scroll_
, 0, auto_scroll_period_
);
891 auto_scroll_
.dx_
= sx
;
892 auto_scroll_
.dy_
= sy
;
895 if (auto_scroll_
!= null) {
896 auto_scroll_
.cancel();
900 scrollBy(-(_event
.x
- mouse_down_x_
), -(_event
.y
- mouse_down_y_
));
906 * Called when mouse is on contents area and button is released
910 protected void contentsMouseUpEvent(MouseEvent _event
) {
911 // reset auto scroll if it's engaged
912 if (auto_scroll_
!= null) {
913 auto_scroll_
.cancel();
919 * Responsible to draw contents area. At least rectangle clipX must be redrawn. This rectangle is given in contents
920 * coordinates. By default, no paint is produced.
928 protected void drawContents(GC gc
, int clipx
, int clipy
, int clipw
, int cliph
) {
932 * Change the size of the contents area.
934 * @param width new width of the area.
935 * @param height new height of the area.
937 public void resizeContents(int width
, int height
) {
938 // System.out.println("SV--resizeContents("+_w+","+_h+" ) {");
946 int oldW
= contents_width_
;
947 int oldH
= contents_height_
;
949 if (width
== oldW
&& height
== oldH
) {
953 // System.out.println("RESIZE-CONTENTS("+_w+","+_h+")");
954 contents_width_
= width
;
955 contents_height_
= height
;
963 int vis_width
= getVisibleWidth();
964 int vis_height
= getVisibleHeight();
965 if (oldW
< vis_width
) {
966 if (width
> vis_width
) {
969 viewcontrol_
.redraw(getContentsX() + oldW
, 0, width
- oldW
, vis_height
, true);
978 if (oldH
< vis_height
) {
979 if (height
> vis_height
) {
982 viewcontrol_
.redraw(0, getContentsY() + oldH
, vis_width
, height
- oldH
, true);
984 if (updateScrollBarVisiblity()) {
987 updateScrollBarsValues();
989 // System.out.println("SV--resizeContents() }");
992 // redefined for internal use ..
994 public void redraw() {
996 // ..need to redraw this already:
997 viewcontrol_
.redraw();
1004 public void scrollBy(int _dx
, int _dy
) {
1005 setContentsPos(getContentsX() + _dx
, getContentsY() + _dy
);
1009 * Scroll to ensure point(in contents coordinates) is visible.
1011 public void ensureVisible(int _px
, int _py
) {
1012 int cx
= getContentsX(), cy
= getContentsY();
1013 int right
= getContentsX() + getVisibleWidth();
1014 int bottom
= getContentsY() + getVisibleHeight();
1015 if (_px
< getContentsX()) {
1017 } else if (_px
> right
) {
1018 cx
= _px
- getVisibleWidth();
1020 if (_py
< getContentsY()) {
1022 } else if (_py
> bottom
) {
1023 cy
= _py
- getVisibleHeight();
1025 setContentsPos(cx
, cy
);
1029 * Make rectangle (_x,_y,_w,_h, in contents coordinates) visible. if rectangle cannot be completely visible, use
1032 * @param _x x contents coordinates of rectangle.
1033 * @param _y y contents coordinates of rectangle.
1034 * @param _w width of rectangle.
1035 * @param _h height of rectangle.
1036 * @param _align bit or'ed SWT flag like SWT.LEFT,RIGHT,CENTER,TOP,BOTTOM,VERTICAL used only for bigger rectangle
1037 * than visible area. By default CENTER/VERTICAL
1039 public void ensureVisible(int _x
, int _y
, int _w
, int _h
, int _align
) {
1040 ensureVisible(_x
, _y
, _w
, _h
, _align
, false);
1044 * Make rectangle (_x,_y,_w,_h, in contents coordinates) visible. if rectangle cannot be completely visible, use
1047 * @param _x x contents coordinates of rectangle.
1048 * @param _y y contents coordinates of rectangle.
1049 * @param _w width of rectangle.
1050 * @param _h height of rectangle.
1051 * @param _align bit or'ed SWT flag like SWT.LEFT,RIGHT,CENTER,TOP,BOTTOM,VERTICAL used only for bigger rectangle
1052 * than visible area. By default CENTER/VERTICAL
1053 * @param forceAlign force alignment for rectangle smaller than the visible area
1055 protected void ensureVisible(int _x
, int _y
, int _w
, int _h
, int _align
, boolean forceAlign
) {
1064 int hbar
= getHorizontalBarHeight();
1065 int vbar
= getVerticalBarWidth();
1066 int cx
= getContentsX(), cy
= getContentsY();
1067 int right
= getContentsX() + getVisibleWidth() - vbar
;
1068 int bottom
= getContentsY() + getVisibleHeight() - hbar
;
1069 boolean align_h
= false, align_v
= false;
1071 if (_x
< getContentsX()) {
1073 } else if (_x
+ _w
> right
) {
1076 if (_y
< getContentsY()) {
1078 } else if (_y
+ _h
> bottom
) {
1082 if (_w
> getVisibleWidth()) {
1085 if (_h
> getVisibleHeight()) {
1088 // compute alignment on visible area horizontally
1089 if (align_h
|| (forceAlign
&& _x
+ _w
> right
)) {
1091 if ((_align
& SWT
.LEFT
) != 0) {
1093 } else if ((_align
& SWT
.RIGHT
) != 0) {
1096 cx
= _x
+ (_w
- getVisibleWidth()) / 2;
1099 // compute alignment on visible area vertically
1100 if (align_v
|| (forceAlign
&& _y
+ _h
> bottom
)) {
1102 if ((_align
& SWT
.TOP
) != 0) {
1104 } else if ((_align
& SWT
.BOTTOM
) != 0) {
1107 cy
= _y
+ (_h
- getVisibleHeight()) / 2;
1110 setContentsPos(cx
, cy
);
1114 * Returns true if point is visible (expressed in contents coordinates).
1116 * @return true if point is visible (expressed in contents coordinates)
1118 public boolean isVisible(int _px
, int _py
) {
1119 if (_px
< getContentsX()) {
1122 if (_py
< getContentsY()) {
1125 if (_px
> (getContentsX() + getVisibleWidth())) {
1128 if (_py
> (getContentsY() + getVisibleHeight())) {
1135 * Returns true if rectangle if partially visible.
1137 * @return true if rectangle if partially visible.
1139 public boolean isVisible(int _x
, int _y
, int _w
, int _h
) {
1140 if (_x
+ _w
< getContentsX()) {
1143 if (_y
+ _h
< getContentsY()) {
1146 int vr
= getContentsX() + getVisibleWidth();
1147 int vb
= getContentsY() + getVisibleHeight();
1158 * Returns visible part of rectangle, or null if rectangle is not visible. Rectangle is expressed in contents
1160 * @return visible part of rectangle, or null if rectangle is not visible.
1162 public Rectangle
getVisiblePart(int _x
, int _y
, int _w
, int _h
) {
1163 if (_x
+ _w
< getContentsX()) {
1166 if (_y
+ _h
< getContentsY()) {
1169 int vr
= getContentsX() + getVisibleWidth();
1170 int vb
= getContentsY() + getVisibleHeight();
1177 int rr
= _x
+ _w
, rb
= _y
+ _h
;
1178 int nl
= Math
.max(_x
, getContentsX()), nt
= Math
.max(_y
, getContentsY()), nr
= Math
.min(rr
, vr
), nb
= Math
.min(rb
, vb
);
1179 Rectangle c
= new Rectangle(nl
, nt
, nr
- nl
, nb
- nt
);
1184 * Returns the visible part for given rectangle.
1186 * @param _r A rectangle
1188 * @return gets visible part of rectangle (or <code>null</code>)
1190 public final Rectangle
getVisiblePart(Rectangle _r
) {
1194 return getVisiblePart(_r
.x
, _r
.y
, _r
.width
, _r
.height
);
1198 * Change top left position of visible area. Check if the given point is inside contents area.
1200 * @param _x x contents coordinates of visible area.
1201 * @param _y y contents coordinates of visible area.
1202 * @return true if view really moves
1204 public boolean setContentsPos(int _x
, int _y
) {
1205 int nx
= _x
, ny
= _y
;
1206 if (getVisibleWidth() >= getContentsWidth()) {
1211 } else if (_x
+ getVisibleWidth() > getContentsWidth()) {
1212 nx
= getContentsWidth() - getVisibleWidth();
1215 if (getVisibleHeight() >= getContentsHeight()) {
1220 } else if (_y
+ getVisibleHeight() > getContentsHeight()) {
1221 ny
= getContentsHeight() - getVisibleHeight();
1225 if (nx
== contents_x_
&& ny
== contents_y_
) {
1230 updateScrollBarsValues();
1231 // ? find smallest area to redraw only them ?
1232 viewcontrol_
.redraw();
1236 // redefined to return our vertical bar
1239 * @see org.eclipse.swt.widgets.Scrollable#getVerticalBar()
1242 public ScrollBar
getVerticalBar() {
1243 return vertsb_
.getVerticalBar();
1246 // redefined to return out horizontal bar
1249 * @see org.eclipse.swt.widgets.Scrollable#getHorizontalBar()
1252 public ScrollBar
getHorizontalBar() {
1253 return horzsb_
.getHorizontalBar();
1257 * Compute visibility of vertical/horizontal bar using given width/height and current visibility (i.e. is bar size are already in
1259 * @param for_width width of foreground
1260 * @param for_height height of foreground
1261 * @param curr_h_vis The current visibility state of horizontal scroll bar
1262 * @param curr_v_vis The current visibility state of vertical scroll bar
1263 * @return <code>true</code> if visibility changed else <code>false</code>
1265 public int computeBarVisibility(int for_width
, int for_height
, boolean curr_h_vis
, boolean curr_v_vis
) {
1267 switch (v_scrollbar_mode_
) {
1274 if (getContentsHeight() > for_height
) {
1276 // v bar size is already in for_width.
1277 if (!curr_v_vis
) {// (curr_vis&0x01)==0)
1278 for_width
-= getVerticalBarWidth();
1284 switch (h_scrollbar_mode_
) {
1291 if (getContentsWidth() > for_width
) {
1293 // h bar is not in for_height
1294 if (!curr_h_vis
)// (curr_vis&0x02)==0 )
1296 if (getContentsHeight() > for_height
- getHorizontalBarHeight()) {
1307 * setup scroll bars visibility, return true if one of visibility changed.
1309 protected boolean updateScrollBarVisiblity() {
1310 boolean change
= false;
1312 boolean curr_v_vis
= vertsb_
.getVisible();
1313 boolean curr_h_vis
= horzsb_
.getVisible();
1314 int bar_new_vis
= computeBarVisibility(getVisibleWidth(), getVisibleHeight(), curr_h_vis
, curr_v_vis
);
1315 boolean new_v_vis
= (bar_new_vis
& VBAR
) != 0;
1316 boolean new_h_vis
= (bar_new_vis
& HBAR
) != 0;
1317 // System.out.println("SV--updateScrollBarVis old, h:"+curr_h_vis+" v:"+curr_v_vis+" new="+bar_new_vis);
1318 if (curr_v_vis ^ new_v_vis
) // vertsb_.getVisible() )
1320 vertsb_
.setVisible(new_v_vis
);
1323 if (curr_h_vis ^ new_h_vis
) {
1324 horzsb_
.setVisible(new_h_vis
);
1328 // update corner control visibility:
1329 if (corner_control_
!= null && change
) {
1330 boolean vis
= new_v_vis
|| new_h_vis
;
1331 if (vis ^ corner_control_
.getVisible()) {
1332 corner_control_
.setVisible(vis
);
1333 change
= true; // but must be already the case
1340 * Setup scroll bar using contents, visible and scroll bar mode properties.
1342 protected void updateScrollBarsValues() {
1343 // System.out.println("UPDATE-SCROLL-BAR-VALUES");
1344 /* update vertical scrollbar */
1345 ScrollBar b
= getVerticalBar();
1348 b
.setMaximum(getContentsHeight());
1349 b
.setThumb(getVisibleHeight());
1350 b
.setPageIncrement(getVisibleHeight());
1351 b
.setIncrement(v_scrollbar_increment_
);
1352 b
.setSelection(getContentsY());
1355 // update "hidden" vertical bar too
1356 b
= viewcontrol_
.getVerticalBar();
1359 b
.setMaximum(getContentsHeight());
1360 b
.setThumb(getVisibleHeight());
1361 b
.setPageIncrement(getVisibleHeight());
1362 b
.setIncrement(v_scrollbar_increment_
);
1363 b
.setSelection(getContentsY());
1366 /* update horizontal scrollbar */
1367 b
= getHorizontalBar();
1370 b
.setMaximum(getContentsWidth());
1371 b
.setThumb(getVisibleWidth());
1372 b
.setSelection(getContentsX());
1373 b
.setPageIncrement(getVisibleWidth());
1374 b
.setIncrement(h_scrollbar_increment_
);
1376 // update "hidden" horizontal bar too
1377 b
= viewcontrol_
.getHorizontalBar();
1380 b
.setMaximum(getContentsWidth());
1381 b
.setThumb(getVisibleWidth());
1382 b
.setSelection(getContentsX());
1383 b
.setPageIncrement(getVisibleWidth());
1384 b
.setIncrement(h_scrollbar_increment_
);
1389 * Change the control used in the bottom right corner (between two scrollbar), if control is null reset previous
1390 * corner control. This control is visible only if at least one scrollbar is visible. Given control will be disposed
1391 * by ScrollView, at dispose() time, at next setCornetControl() call or when calling setOverviewEnabled(). Pay
1392 * attention calling this reset overview feature until setOverviewEnabled(true) if called.
1393 * @param _w The control for the overview
1395 public void setCornerControl(Control _w
) {
1396 if (corner_control_
!= null) {
1397 corner_control_
.dispose();
1399 corner_control_
= _w
;
1400 if (corner_control_
!= null) {
1401 ScrollBar vb
= getVerticalBar();
1402 ScrollBar hb
= getHorizontalBar();
1403 boolean vis
= vb
.getVisible() || hb
.getVisible();
1404 corner_control_
.setVisible(vis
);
1409 * Transform (x,y) point in widget coordinates to contents coordinates.
1411 * @param x The x widget coordinate.
1412 * @param y The y widget coordinate.
1413 * @return org.eclipse.swt.graphics.Point with content coordinates.
1415 public final Point
viewToContents(int x
, int y
) {
1416 Point p
= new Point(viewToContentsX(x
), viewToContentsY(y
));
1421 * Transform x in widget coordinates to contents coordinates
1423 * @param _x The y widget coordinate.
1424 * @return the x content coordinate.
1426 public int viewToContentsX(int _x
) {
1427 return contents_x_
+ _x
;
1431 * Transform y in widget coordinates to contents coordinates
1433 * @param _y The y widget coordinate.
1434 * @return the y content coordinate.
1436 public int viewToContentsY(int _y
) {
1437 return contents_y_
+ _y
;
1441 * Transform (x,y) point from contents coordinates, to widget coordinates.
1443 * @param x The x content coordinate.
1444 * @param y The y content coordinate.
1445 * @return coordinates widget area as.
1447 public final Point
contentsToView(int x
, int y
) {
1448 Point p
= new Point(contentsToViewX(x
), contentsToViewY(y
));
1453 * Transform X axis coordinates from contents to widgets.
1455 * @param _x contents coordinate to transform.
1456 * @return x coordinate in widget area
1458 public int contentsToViewX(int _x
) {
1459 return _x
- contents_x_
;
1463 * Transform Y axis coordinates from contents to widgets.
1465 * @param _y contents coordinate to transform
1466 * @return y coordinate in widget area
1468 public int contentsToViewY(int _y
) {
1469 return _y
- contents_y_
;
1473 * Return the visible height of scroll view, might be > contentsHeight
1475 * @return the visible height of scroll view, might be > contentsHeight()
1477 public int getVisibleHeight() {
1478 Rectangle r
= viewcontrol_
.getClientArea();
1483 * Return int the visible width of scroll view, might be > contentsWidth().
1485 * @return int the visible width of scroll view, might be > contentsWidth()
1487 public int getVisibleWidth() {
1488 Rectangle r
= viewcontrol_
.getClientArea();
1493 * Add support for arrow key, scroll the ... scroll view. But you can redefine this method for your convenience.
1495 protected void keyPressedEvent(KeyEvent _e
) {
1496 switch (_e
.keyCode
) {
1498 scrollBy(0, -getVisibleHeight());
1500 case SWT
.ARROW_DOWN
:
1501 scrollBy(0, +getVisibleHeight());
1503 case SWT
.ARROW_LEFT
:
1504 scrollBy(-getVisibleWidth(), 0);
1506 case SWT
.ARROW_RIGHT
:
1507 scrollBy(+getVisibleWidth(), 0);
1513 * Redefine this method at your convenience
1514 * @param _e The key event.
1516 protected void keyReleasedEvent(KeyEvent _e
) {
1520 * Called when ScrollView view is resized.
1522 protected void viewResized() {
1523 // System.out.println("SV--viewResizeEvent()");
1524 // scroll contents x,y if visible area bigger than contents...
1525 if (!setContentsPos(getContentsX(), getContentsY())) {
1526 // if no scroll done, scroll bar must be updated.
1528 * if( ocx==getContentsX() && ocy==getContentsY() ) { updateScrollBars(); }
1534 * Returns vertical bar width, even if bar isn't visible.
1536 * @return vertical bar width, even if bar isn't visible
1538 public int getVerticalBarWidth() {
1539 // include vertical bar width and trimming of scrollable used
1540 int bw
= vertsb_
.computeTrim(0, 0, 0, 0).width
;
1545 * Returns horizontal bar height even if bar isn't visible.
1547 * @return horizontal bar height even if bar isn't visible
1549 public int getHorizontalBarHeight() {
1550 // include horiz. bar height and trimming of scrollable used
1551 int bh
= horzsb_
.computeTrim(0, 0, 0, 0).height
;
1552 // +1 because win32 H.bar need 1 pixel canvas size to appear ! (strange no ?)
1558 * @see org.eclipse.swt.widgets.Scrollable#computeTrim(int, int, int, int)
1561 public Rectangle
computeTrim(int x
, int y
, int w
, int h
) {
1562 Rectangle r
= new Rectangle(x
, y
, w
, h
);
1563 int bar_vis
= computeBarVisibility(w
, h
, false, false);
1564 if ((bar_vis
& VBAR
) != 0) {
1565 r
.width
+= getVerticalBarWidth();
1567 if ((bar_vis
& HBAR
) != 0) {
1568 r
.height
+= getHorizontalBarHeight();
1574 * Internal layout for ScrollView, handle scrollbars, drawzone and corner control
1576 protected class SVLayout
extends Layout
{
1578 boolean dont_layout
= false;
1582 * @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite, int, int, boolean)
1585 protected Point
computeSize(Composite composite
, int wHint
, int hHint
, boolean flushCache
) {
1586 Point p
= new Point(250, 250);
1587 if (contents_width_
< p
.x
) {
1588 p
.x
= contents_width_
;
1590 if (contents_height_
< p
.y
) {
1591 p
.y
= contents_height_
;
1598 * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite, boolean)
1601 protected void layout(Composite composite
, boolean flushCache
) {
1610 // System.out.println(">>> SV.layout() {");
1611 Point cs
= composite
.getSize();
1612 int bar_vis
= computeBarVisibility(cs
.x
, cs
.y
, false, false);
1613 boolean vb_vis
= (bar_vis
& VBAR
) != 0;
1614 boolean hb_vis
= (bar_vis
& HBAR
) != 0;
1615 vertsb_
.setVisible(vb_vis
);
1616 horzsb_
.setVisible(hb_vis
);
1617 int vbw
= getVerticalBarWidth();
1618 int hbh
= getHorizontalBarHeight();
1619 int wb
= vb_vis ? vbw
: 0;
1620 int hb
= hb_vis ? hbh
: 0;
1621 int cww
= 0, cwh
= 0;
1622 // System.out.println("SV-LAYOUT H.vis="+hb_vis+" V.vis="+vb_vis);
1624 if (corner_control_
!= null && (vb_vis
|| hb_vis
)) { // corner_control_.getVisible())
1625 corner_control_
.setVisible(true);
1632 } else if (vb_vis
&& hb_vis
) {
1633 if (corner_control_
!= null) {
1634 corner_control_
.setVisible(false);
1639 if (vb_vis
|| hb_vis
) {
1640 updateScrollBarsValues();
1643 int vw
= cs
.x
- (vb_vis ? vbw
: 0);
1644 int vh
= cs
.y
- (hb_vis ? hbh
: 0);
1645 int vbx
= cs
.x
- wb
;
1646 int hby
= cs
.y
- hb
;
1647 Rectangle rc
= viewcontrol_
.getClientArea();
1648 int old_width
= rc
.width
;
1649 int old_height
= rc
.height
;
1650 // provoque pas un viewResize ???
1651 viewcontrol_
.setBounds(0, 0, vw
, vh
);
1652 boolean do_view_resize
= false;
1653 rc
= viewcontrol_
.getClientArea();
1654 if (old_width
!= rc
.width
|| old_height
!= rc
.height
) {
1655 // area size change, so visibleWidth()/Height() change too
1656 // so scrollbars visibility ma change too..
1657 // so need an other layout !
1659 * if( updateScrollBarVisiblity() ) { layout( composite, flushCache);
1660 * System.out.println("<<< SV.layout() } (recursive)"); return ; }
1662 do_view_resize
= true;
1665 vertsb_
.setBounds(vbx
, 0, wb
, cs
.y
- cwh
);
1668 horzsb_
.setBounds(0, hby
, cs
.x
- cww
, hb
);
1670 if (corner_control_
!= null && corner_control_
.getVisible()) {
1671 corner_control_
.setBounds(vbx
, hby
, vbw
, hbh
);
1673 updateScrollBarsValues();
1674 if (do_view_resize
) {
1675 // System.out.println(" -layout do_view_resize old="+old_width+"x"+old_height+" new="+viewcontrol_.getClientArea());
1678 // System.out.println("<<< SV.layout() }");
1681 dont_layout
= false;
1686 // static must take place here... cursor is created once.
1687 static Cursor overview_cursor_
;
1689 /** Support for click-and-see overview shell on this ScrollView */
1690 protected class Overview
{
1691 // factors from real and overview sizes, for mouse move speed.
1692 protected float overview_factor_x_
, overview_factor_y_
;
1693 // shell use to show overview
1694 protected Shell overview
;
1695 // save mouse cursor location for disappear();
1696 protected int save_cursor_x
, save_cursor_y
;
1698 /** apply overview support on a control. Replace existing corner_widget */
1699 public void useControl(Control _c
) {
1700 final Point pos
= _c
.getLocation();
1701 _c
.addMouseListener(new MouseListener() {
1703 public void mouseDoubleClick(MouseEvent e
) {
1707 public void mouseDown(MouseEvent e
) {
1708 overviewAppear(e
.x
, e
.y
);
1712 public void mouseUp(MouseEvent e
) {
1713 overviewDisappear();
1717 _c
.addFocusListener(new FocusListener() {
1720 public void focusGained(FocusEvent e
) {
1721 // TODO Auto-generated method stub
1726 public void focusLost(FocusEvent e
) {
1728 overviewDisappear(false);
1732 _c
.addKeyListener(new KeyListener() {
1735 public void keyPressed(KeyEvent e
) {
1736 if (e
.keyCode
== 32 && !overviewing()) {
1737 overviewAppear(pos
.x
, pos
.y
);
1738 } else if (e
.keyCode
== 32) {
1739 overviewDisappear();
1741 if (e
.keyCode
== SWT
.ARROW_DOWN
) {
1742 overviewMove(0, 1, e
);
1745 if (e
.keyCode
== SWT
.ARROW_UP
) {
1746 overviewMove(0, -1, e
);
1749 if (e
.keyCode
== SWT
.ARROW_RIGHT
) {
1750 overviewMove(1, 0, e
);
1753 if (e
.keyCode
== SWT
.ARROW_LEFT
) {
1754 overviewMove(-1, 0, e
);
1759 public void keyReleased(KeyEvent e
) {
1762 _c
.addMouseMoveListener(new MouseMoveListener() {
1763 private int refReshCount
= 0;
1765 public void mouseMove(MouseEvent e
) {
1766 if (overviewing()) {
1767 // Slow down the refresh
1768 if (refReshCount
% 4 == 0) {
1778 * Dispose controls of overview
1780 public void dispose() {
1781 if (overview
!= null) {
1787 * @return true if overview is currently on screen
1789 protected boolean overviewing() {
1790 return (overview
!= null && overview
.isVisible());
1794 * Process overview appear
1796 protected void overviewAppear(int mx
, int my
) {
1797 if (overview
== null) {
1798 overview
= new Shell(getShell(), SWT
.ON_TOP
| SWT
.NO_BACKGROUND
);
1799 overview
.addPaintListener(new PaintListener() {
1801 public void paintControl(PaintEvent e
) {
1802 drawOverview(e
.gc
, overview
.getClientArea());
1806 // always the same..
1807 // overview.setBackground( viewcontrol_.getBackground() );
1808 overview
.setForeground(viewcontrol_
.getForeground());
1810 // get location of shell (in screeen coordinates)
1811 Point p
= toGlobalCoordinates(corner_control_
, 0, 0);
1815 w
= h
= overview_size_
;
1816 Rectangle scr
= getDisplay().getBounds();
1817 Point ccs
= corner_control_
.getSize();
1819 if (contents_width_
> contents_height_
) {
1820 float ratio
= contents_height_
/ (float) contents_width_
;
1821 h
= (int) (w
* ratio
);
1824 } else if (h
>= scr
.height
/ 2) {
1828 float ratio
= contents_width_
/ (float) contents_height_
;
1829 w
= (int) (h
* ratio
);
1832 } else if (w
>= scr
.width
/ 2) {
1836 overview_factor_x_
= contents_width_
/ (float) w
;
1837 overview_factor_y_
= contents_height_
/ (float) h
;
1839 // no contents size set ?
1840 catch (java
.lang
.ArithmeticException e
) {
1843 // try pop-up on button, extending to bottom right,
1844 // if outside screen, extend pop-up to top left
1845 // if( x+w > scr.width ) x = scr.width-w; //x += corner_control_.getSize().x-w;
1846 // if( y+h > scr.height ) y = scr.height-h;//y += corner_control_.getSize().y-h;
1855 overview
.setBounds(x
, y
, w
, h
);
1856 overview
.setVisible(true);
1858 // mouse cursor disappear, so set invisible mouse cursor ...
1859 if (overview_cursor_
== null) {
1860 RGB rgb
[] = { new RGB(0, 0, 0), new RGB(255, 0, 0) };
1861 PaletteData pal_
= new PaletteData(rgb
);
1863 byte src
[] = new byte[s
* s
];
1864 byte msk
[] = new byte[s
* s
];
1865 for (int i
= 0; i
< s
* s
; ++i
)
1866 src
[i
] = (byte) 0xFF;
1867 ImageData i_src
= new ImageData(s
, s
, 1, pal_
, 1, src
);
1868 ImageData i_msk
= new ImageData(s
, s
, 1, pal_
, 1, msk
);
1869 overview_cursor_
= new Cursor(null, i_src
, i_msk
, 0, 0);
1871 corner_control_
.setCursor(overview_cursor_
);
1872 // convert to global coordinates
1873 p
= toGlobalCoordinates(corner_control_
, mx
, my
);
1874 save_cursor_x
= p
.x
;
1875 save_cursor_y
= p
.y
;
1877 Rectangle r
= overview
.getClientArea();
1878 int cx
= (int) (r
.width
* contents_x_
/ (float) contents_width_
);
1879 int cy
= (int) (r
.height
* contents_y_
/ (float) contents_height_
);
1881 // cx,cy to display's global coordinates
1882 p
= toGlobalCoordinates(overview
.getParent(), cx
, cy
);
1889 * Process disappear of overview
1891 protected void overviewDisappear() {
1892 overviewDisappear(true);
1896 * Process disappear of overview
1897 * @param restoreCursorLoc A flag to restore cursor location
1899 protected void overviewDisappear(boolean restoreCursorLoc
) {
1900 if (overview
== null)
1902 overview
.setVisible(false);
1903 corner_control_
.setCursor(null);
1904 if (restoreCursorLoc
) {
1905 getDisplay().setCursorLocation(save_cursor_x
, save_cursor_y
);
1912 * Process mouse move in overview
1913 * @param event The mouse event
1915 protected void overviewMove(MouseEvent event
) {
1916 Point p
= toGlobalCoordinates(corner_control_
, event
.x
, event
.y
);
1917 int dx
= p
.x
- save_cursor_x
;
1918 int dy
= p
.y
- save_cursor_y
;
1919 overviewMove(dx
, dy
, event
);
1923 * Process mouse move event when overviewing
1925 * @param dx The x coordinates delta
1926 * @param dy The y coordinates delta
1927 * @param event The typed event
1929 protected void overviewMove(int dx
, int dy
, TypedEvent event
) {
1930 boolean ctrl
= false;
1931 boolean shift
= false;
1933 if (event
instanceof MouseEvent
) {
1934 MouseEvent e
= (MouseEvent
) event
;
1935 getDisplay().setCursorLocation(save_cursor_x
, save_cursor_y
);
1936 ctrl
= (e
.stateMask
& SWT
.CONTROL
) != 0;
1937 shift
= (e
.stateMask
& SWT
.SHIFT
) != 0;
1938 } else if (event
instanceof KeyEvent
) {
1939 KeyEvent e
= (KeyEvent
) event
;
1940 ctrl
= (e
.stateMask
& SWT
.CONTROL
) != 0;
1941 shift
= (e
.stateMask
& SWT
.SHIFT
) != 0;
1944 int cx
= contents_x_
;
1945 int cy
= contents_y_
;
1946 float fx
= overview_factor_x_
;
1947 float fy
= overview_factor_y_
;
1949 if (ctrl
&& shift
) {
1950 if ((fx
* 0.25f
> 1) && (fy
* 0.25 > 1)) {
1963 scrollBy((int) (fx
* dx
), (int) (fy
* dy
));
1964 if (cx
!= contents_x_
|| cy
!= contents_y_
) {
1966 overview
.update(); // draw now !
1971 * Convert overview coordinates to global coordinates.
1973 * @param _loc the control reference
1974 * @param _x The x coordinate to convert
1975 * @param _y The y coordinate to convert
1978 protected Point
toGlobalCoordinates(Control _loc
, int _x
, int _y
) {
1979 Point p
= new Point(_x
, _y
);
1980 for (Control c
= _loc
; c
!= null; c
= c
.getParent()) {
1981 // control might have client area with 'decorations'
1982 int trim_x
= 0, trim_y
= 0;
1983 // other kind of widget with trimming ??
1984 if (c
instanceof Scrollable
) {
1985 Scrollable s
= (Scrollable
) c
;
1986 Rectangle rr
= s
.getClientArea();
1987 Rectangle tr
= s
.computeTrim(rr
.x
, rr
.y
, rr
.width
, rr
.height
);
1988 trim_x
= rr
.x
- tr
.x
;
1989 trim_y
= rr
.y
- tr
.y
;
1991 p
.x
+= c
.getLocation().x
+ trim_x
;
1992 p
.y
+= c
.getLocation().y
+ trim_y
;