1 /*******************************************************************************
2 * Copyright (c) 2000, 2012 IBM Corporation and others.
3 *
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
8 *
9 * SPDX-License-Identifier: EPL-2.0
10 *
11 * Contributors:
12 * IBM Corporation - initial API and implementation
13 *******************************************************************************/
14 package org.eclipse.swt.widgets;
15
16
17 import org.eclipse.swt.*;
18 import org.eclipse.swt.events.*;
19 import org.eclipse.swt.graphics.*;
20 import org.eclipse.swt.internal.cocoa.*;
21
22 /**
23 * Instances of this class are selectable user interface
24 * objects that represent a range of positive, numeric values.
25 * <p>
26 * At any given moment, a given scroll bar will have a
27 * single 'selection' that is considered to be its
28 * value, which is constrained to be within the range of
29 * values the scroll bar represents (that is, between its
30 * <em>minimum</em> and <em>maximum</em> values).
31 * </p><p>
32 * Typically, scroll bars will be made up of five areas:</p>
33 * <ol>
34 * <li>an arrow button for decrementing the value</li>
35 * <li>a page decrement area for decrementing the value by a larger amount</li>
36 * <li>a <em>thumb</em> for modifying the value by mouse dragging</li>
37 * <li>a page increment area for incrementing the value by a larger amount</li>
38 * <li>an arrow button for incrementing the value</li>
39 * </ol>
40 * <p>
41 * Based on their style, scroll bars are either <code>HORIZONTAL</code>
42 * (which have a left facing button for decrementing the value and a
43 * right facing button for incrementing it) or <code>VERTICAL</code>
44 * (which have an upward facing button for decrementing the value
45 * and a downward facing buttons for incrementing it).
46 * </p><p>
47 * On some platforms, the size of the scroll bar's thumb can be
48 * varied relative to the magnitude of the range of values it
49 * represents (that is, relative to the difference between its
50 * maximum and minimum values). Typically, this is used to
51 * indicate some proportional value such as the ratio of the
52 * visible area of a document to the total amount of space that
53 * it would take to display it. SWT supports setting the thumb
54 * size even if the underlying platform does not, but in this
55 * case the appearance of the scroll bar will not change.
56 * </p><p>
57 * Scroll bars are created by specifying either <code>H_SCROLL</code>,
58 * <code>V_SCROLL</code> or both when creating a <code>Scrollable</code>.
59 * They are accessed from the <code>Scrollable</code> using
60 * <code>getHorizontalBar</code> and <code>getVerticalBar</code>.
61 * </p><p>
62 * Note: Scroll bars are not Controls. On some platforms, scroll bars
63 * that appear as part of some standard controls such as a text or list
64 * have no operating system resources and are not children of the control.
65 * For this reason, scroll bars are treated specially. To create a control
66 * that looks like a scroll bar but has operating system resources, use
67 * <code>Slider</code>.
68 * </p>
69 * <dl>
70 * <dt><b>Styles:</b></dt>
71 * <dd>HORIZONTAL, VERTICAL</dd>
72 * <dt><b>Events:</b></dt>
73 * <dd>Selection</dd>
74 * </dl>
75 * <p>
76 * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
77 * </p><p>
78 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
79 * </p>
80 *
81 * @see Slider
82 * @see Scrollable
83 * @see Scrollable#getHorizontalBar
84 * @see Scrollable#getVerticalBar
85 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample</a>
86 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
87 * @noextend This class is not intended to be subclassed by clients.
88 */
89 public class ScrollBar extends Widget {
90 NSScroller view;
91 Scrollable parent;
92 int minimum, maximum = 100, thumb = 10;
93 int increment = 1;
94 int pageIncrement = 10;
95 id target;
96 long actionSelector;
97
ScrollBar()98 ScrollBar () {
99 /* Do nothing */
100 }
101
102 /**
103 * Adds the listener to the collection of listeners who will
104 * be notified when the user changes the receiver's value, by sending
105 * it one of the messages defined in the <code>SelectionListener</code>
106 * interface.
107 * <p>
108 * When <code>widgetSelected</code> is called, the event object detail field contains one of the following values:
109 * <code>SWT.NONE</code> - for the end of a drag.
110 * <code>SWT.DRAG</code>.
111 * <code>SWT.HOME</code>.
112 * <code>SWT.END</code>.
113 * <code>SWT.ARROW_DOWN</code>.
114 * <code>SWT.ARROW_UP</code>.
115 * <code>SWT.PAGE_DOWN</code>.
116 * <code>SWT.PAGE_UP</code>.
117 * <code>widgetDefaultSelected</code> is not called.
118 * </p>
119 *
120 * @param listener the listener which should be notified when the user changes the receiver's value
121 *
122 * @exception IllegalArgumentException <ul>
123 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
124 * </ul>
125 * @exception SWTException <ul>
126 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
127 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
128 * </ul>
129 *
130 * @see SelectionListener
131 * @see #removeSelectionListener
132 * @see SelectionEvent
133 */
addSelectionListener(SelectionListener listener)134 public void addSelectionListener(SelectionListener listener) {
135 checkWidget();
136 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
137 TypedListener typedListener = new TypedListener(listener);
138 addListener(SWT.Selection,typedListener);
139 addListener(SWT.DefaultSelection,typedListener);
140 }
141
checkStyle(int style)142 static int checkStyle (int style) {
143 return checkBits (style, SWT.HORIZONTAL, SWT.VERTICAL, 0, 0, 0, 0);
144 }
145
146 @Override
deregister()147 void deregister () {
148 super.deregister ();
149 display.removeWidget (view);
150 }
151
152 @Override
getDrawing()153 boolean getDrawing () {
154 return parent.getDrawing ();
155 }
156
157 /**
158 * Returns <code>true</code> if the receiver is enabled, and
159 * <code>false</code> otherwise. A disabled control is typically
160 * not selectable from the user interface and draws with an
161 * inactive or "grayed" look.
162 *
163 * @return the receiver's enabled state
164 *
165 * @exception SWTException <ul>
166 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
167 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
168 * </ul>
169 *
170 * @see #isEnabled
171 */
getEnabled()172 public boolean getEnabled () {
173 checkWidget();
174 return (state & DISABLED) == 0;
175 }
176
177 /**
178 * Returns the amount that the receiver's value will be
179 * modified by when the up/down (or right/left) arrows
180 * are pressed.
181 *
182 * @return the increment
183 *
184 * @exception SWTException <ul>
185 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
186 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
187 * </ul>
188 */
getIncrement()189 public int getIncrement () {
190 checkWidget();
191 return increment;
192 }
193
194 /**
195 * Returns the maximum value which the receiver will allow.
196 *
197 * @return the maximum
198 *
199 * @exception SWTException <ul>
200 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
201 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
202 * </ul>
203 */
getMaximum()204 public int getMaximum () {
205 checkWidget();
206 return maximum;
207 }
208
209 /**
210 * Returns the minimum value which the receiver will allow.
211 *
212 * @return the minimum
213 *
214 * @exception SWTException <ul>
215 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
216 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
217 * </ul>
218 */
getMinimum()219 public int getMinimum () {
220 checkWidget();
221 return minimum;
222 }
223
224 /**
225 * Returns the amount that the receiver's value will be
226 * modified by when the page increment/decrement areas
227 * are selected.
228 *
229 * @return the page increment
230 *
231 * @exception SWTException <ul>
232 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
233 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
234 * </ul>
235 */
getPageIncrement()236 public int getPageIncrement () {
237 checkWidget();
238 return pageIncrement;
239 }
240
241 /**
242 * Returns the receiver's parent, which must be a Scrollable.
243 *
244 * @return the receiver's parent
245 *
246 * @exception SWTException <ul>
247 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
248 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
249 * </ul>
250 */
getParent()251 public Scrollable getParent () {
252 checkWidget ();
253 return parent;
254 }
255
256 /**
257 * Returns the single 'selection' that is the receiver's value.
258 *
259 * @return the selection
260 *
261 * @exception SWTException <ul>
262 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
263 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
264 * </ul>
265 */
getSelection()266 public int getSelection () {
267 checkWidget();
268 NSScroller widget = (NSScroller)view;
269 double value = widget.doubleValue();
270 return (int)(0.5f + ((maximum - thumb - minimum) * value + minimum));
271 }
272
273 /**
274 * Returns a point describing the receiver's size. The
275 * x coordinate of the result is the width of the receiver.
276 * The y coordinate of the result is the height of the
277 * receiver.
278 *
279 * @return the receiver's size
280 *
281 * @exception SWTException <ul>
282 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
283 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
284 * </ul>
285 */
getSize()286 public Point getSize () {
287 checkWidget();
288 NSRect rect = ((NSScroller)view).frame();
289 return new Point((int)rect.width, (int)rect.height);
290 }
291
292 /**
293 * Returns the receiver's thumb value.
294 *
295 * @return the thumb value
296 *
297 * @exception SWTException <ul>
298 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
299 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
300 * </ul>
301 *
302 * @see ScrollBar
303 */
getThumb()304 public int getThumb () {
305 checkWidget();
306 return thumb;
307 }
308
309 /**
310 * Returns a rectangle describing the size and location of the
311 * receiver's thumb relative to its parent.
312 *
313 * @return the thumb bounds, relative to the {@link #getParent() parent}
314 *
315 * @exception SWTException <ul>
316 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
317 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
318 * </ul>
319 *
320 * @since 3.6
321 */
getThumbBounds()322 public Rectangle getThumbBounds () {
323 checkWidget();
324 NSRect rect = view.rectForPart(OS.NSScrollerKnob);
325 rect = view.convertRect_toView_(rect, parent.view);
326 return new Rectangle((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
327 }
328
329 /**
330 * Returns a rectangle describing the size and location of the
331 * receiver's thumb track relative to its parent. This rectangle
332 * comprises the areas 2, 3, and 4 as described in {@link ScrollBar}.
333 *
334 * @return the thumb track bounds, relative to the {@link #getParent() parent}
335 *
336 * @exception SWTException <ul>
337 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
338 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
339 * </ul>
340 *
341 * @since 3.6
342 */
getThumbTrackBounds()343 public Rectangle getThumbTrackBounds () {
344 checkWidget();
345 NSRect rect = view.rectForPart(OS.NSScrollerKnobSlot);
346 rect = view.convertRect_toView_(rect, parent.view);
347 return new Rectangle((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
348 }
349
350 /**
351 * Returns <code>true</code> if the receiver is visible, and
352 * <code>false</code> otherwise.
353 * <p>
354 * If one of the receiver's ancestors is not visible or some
355 * other condition makes the receiver not visible, this method
356 * may still indicate that it is considered visible even though
357 * it may not actually be showing.
358 * </p>
359 *
360 * @return the receiver's visibility state
361 *
362 * @exception SWTException <ul>
363 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
364 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
365 * </ul>
366 */
getVisible()367 public boolean getVisible () {
368 checkWidget();
369 return (state & HIDDEN) == 0 && !view.isHidden();
370 }
371
372 /**
373 * Returns <code>true</code> if the receiver is enabled and all
374 * of the receiver's ancestors are enabled, and <code>false</code>
375 * otherwise. A disabled control is typically not selectable from the
376 * user interface and draws with an inactive or "grayed" look.
377 *
378 * @return the receiver's enabled state
379 *
380 * @exception SWTException <ul>
381 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
382 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
383 * </ul>
384 *
385 * @see #getEnabled
386 */
isEnabled()387 public boolean isEnabled () {
388 checkWidget();
389 return getEnabled () && parent.isEnabled ();
390 }
391
392 @Override
isDrawing()393 boolean isDrawing () {
394 return getDrawing() && parent.isDrawing ();
395 }
396
397 /**
398 * Returns <code>true</code> if the receiver is visible and all
399 * of the receiver's ancestors are visible and <code>false</code>
400 * otherwise.
401 *
402 * @return the receiver's visibility state
403 *
404 * @exception SWTException <ul>
405 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
406 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
407 * </ul>
408 *
409 * @see #getVisible
410 */
isVisible()411 public boolean isVisible () {
412 checkWidget();
413 return getVisible () && parent.isVisible ();
414 }
415
416 /**
417 * Removes the listener from the collection of listeners who will
418 * be notified when the user changes the receiver's value.
419 *
420 * @param listener the listener which should no longer be notified
421 *
422 * @exception IllegalArgumentException <ul>
423 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
424 * </ul>
425 * @exception SWTException <ul>
426 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
427 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
428 * </ul>
429 *
430 * @see SelectionListener
431 * @see #addSelectionListener
432 */
removeSelectionListener(SelectionListener listener)433 public void removeSelectionListener(SelectionListener listener) {
434 checkWidget();
435 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
436 if (eventTable == null) return;
437 eventTable.unhook(SWT.Selection, listener);
438 eventTable.unhook(SWT.DefaultSelection,listener);
439 }
440
441 @Override
register()442 void register () {
443 super.register ();
444 display.addWidget (view, this);
445 }
446
447 @Override
releaseHandle()448 void releaseHandle () {
449 super.releaseHandle ();
450 if (view != null) view.release();
451 view = null;
452 }
453
454 @Override
releaseParent()455 void releaseParent () {
456 super.releaseParent ();
457 if (parent.horizontalBar == this) parent.horizontalBar = null;
458 if (parent.verticalBar == this) parent.verticalBar = null;
459 }
460
461 @Override
releaseWidget()462 void releaseWidget () {
463 super.releaseWidget ();
464 parent = null;
465 }
466
467 @Override
sendSelection()468 void sendSelection () {
469 NSWindow window = view.window ();
470 if (target == null) parent.getShell().deferFlushing();
471 int value = 0;
472 if (target != null) {
473 view.sendAction(actionSelector, target);
474 } else {
475 value = getSelection ();
476 }
477 NSPoint point;
478 NSEvent nsEvent = NSApplication.sharedApplication().currentEvent();
479 if (nsEvent != null) {
480 point = nsEvent.locationInWindow();
481 if (nsEvent.window() == null) point = window.convertScreenToBase(point);
482 } else {
483 point = window.mouseLocationOutsideOfEventStream();
484 }
485 int hitPart = (int)((NSScroller)view).testPart(point);
486 Event event = new Event();
487 switch (hitPart) {
488 case OS.NSScrollerDecrementLine:
489 value -= increment;
490 event.detail = SWT.ARROW_UP;
491 break;
492 case OS.NSScrollerDecrementPage:
493 value -= pageIncrement;
494 event.detail = SWT.PAGE_UP;
495 break;
496 case OS.NSScrollerIncrementLine:
497 value += increment;
498 event.detail = SWT.ARROW_DOWN;
499 break;
500 case OS.NSScrollerIncrementPage:
501 value += pageIncrement;
502 event.detail = SWT.PAGE_DOWN;
503 break;
504 case OS.NSScrollerKnob:
505 event.detail = SWT.DRAG;
506 break;
507 }
508 if (target == null) {
509 if (event.detail != SWT.DRAG) {
510 setSelection(value);
511 }
512 }
513 sendSelectionEvent(SWT.Selection, event, true);
514 }
515
516 /**
517 * Sets the amount that the receiver's value will be
518 * modified by when the up/down (or right/left) arrows
519 * are pressed to the argument, which must be at least
520 * one.
521 *
522 * @param value the new increment (must be greater than zero)
523 *
524 * @exception SWTException <ul>
525 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
526 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
527 * </ul>
528 */
setIncrement(int value)529 public void setIncrement (int value) {
530 checkWidget();
531 if (value < 1) return;
532 increment = value;
533 }
534
535 @Override
setClipRegion(NSView view)536 void setClipRegion (NSView view) {
537 parent.setClipRegion(view);
538 }
539
540 /**
541 * Enables the receiver if the argument is <code>true</code>,
542 * and disables it otherwise. A disabled control is typically
543 * not selectable from the user interface and draws with an
544 * inactive or "grayed" look.
545 *
546 * @param enabled the new enabled state
547 *
548 * @exception SWTException <ul>
549 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
550 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
551 * </ul>
552 */
setEnabled(boolean enabled)553 public void setEnabled (boolean enabled) {
554 checkWidget();
555 if (enabled) {
556 if ((state & DISABLED) == 0) return;
557 state &= ~DISABLED;
558 } else {
559 if ((state & DISABLED) != 0) return;
560 state |= DISABLED;
561 }
562 enableWidget (enabled);
563 }
564
enableWidget(boolean enabled)565 void enableWidget (boolean enabled) {
566 if (!enabled || (state & DISABLED) == 0) {
567 view.setEnabled (enabled);
568 }
569 }
570
571 /**
572 * Sets the maximum. If this value is negative or less than or
573 * equal to the minimum, the value is ignored. If necessary, first
574 * the thumb and then the selection are adjusted to fit within the
575 * new range.
576 *
577 * @param value the new maximum
578 *
579 * @exception SWTException <ul>
580 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
581 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
582 * </ul>
583 */
setMaximum(int value)584 public void setMaximum (int value) {
585 checkWidget();
586 if (value < 0) return;
587 if (value <= minimum) return;
588 if (value - minimum < thumb) {
589 thumb = value - minimum;
590 }
591 int selection = Math.max(minimum, Math.min (getSelection (), value - thumb));
592 this.maximum = value;
593 updateBar(selection, minimum, value, thumb);
594 }
595
596 /**
597 * Sets the minimum value. If this value is negative or greater
598 * than or equal to the maximum, the value is ignored. If necessary,
599 * first the thumb and then the selection are adjusted to fit within
600 * the new range.
601 *
602 * @param value the new minimum
603 *
604 * @exception SWTException <ul>
605 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
606 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
607 * </ul>
608 */
setMinimum(int value)609 public void setMinimum (int value) {
610 checkWidget();
611 if (value < 0) return;
612 if (value >= maximum) return;
613 if (maximum - value < thumb) {
614 thumb = maximum - value;
615 }
616 int selection = Math.min(maximum - thumb, Math.max (getSelection (), value));
617 this.minimum = value;
618 updateBar(selection, value, maximum, thumb);
619 }
620
621 /**
622 * Sets the amount that the receiver's value will be
623 * modified by when the page increment/decrement areas
624 * are selected to the argument, which must be at least
625 * one.
626 *
627 * @param value the page increment (must be greater than zero)
628 *
629 * @exception SWTException <ul>
630 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
631 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
632 * </ul>
633 */
setPageIncrement(int value)634 public void setPageIncrement (int value) {
635 checkWidget();
636 if (value < 1) return;
637 pageIncrement = value;
638 }
639
640 /**
641 * Sets the single <em>selection</em> that is the receiver's
642 * value to the argument which must be greater than or equal
643 * to zero.
644 *
645 * @param selection the new selection (must be zero or greater)
646 *
647 * @exception SWTException <ul>
648 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
649 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
650 * </ul>
651 */
setSelection(int selection)652 public void setSelection (int selection) {
653 checkWidget();
654 updateBar(selection, minimum, maximum, thumb);
655 }
656
657 /**
658 * Sets the thumb value. The thumb value should be used to represent
659 * the size of the visual portion of the current range. This value is
660 * usually the same as the page increment value.
661 * <p>
662 * This new value will be ignored if it is less than one, and will be
663 * clamped if it exceeds the receiver's current range.
664 * </p>
665 *
666 * @param value the new thumb value, which must be at least one and not
667 * larger than the size of the current range
668 *
669 * @exception SWTException <ul>
670 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
671 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
672 * </ul>
673 */
setThumb(int value)674 public void setThumb (int value) {
675 checkWidget();
676 if (value < 1) return;
677 value = Math.min (value, maximum - minimum);
678 updateBar(getSelection(), minimum, maximum, value);
679 this.thumb = value;
680 }
681
682 /**
683 * Sets the receiver's selection, minimum value, maximum
684 * value, thumb, increment and page increment all at once.
685 * <p>
686 * Note: This is similar to setting the values individually
687 * using the appropriate methods, but may be implemented in a
688 * more efficient fashion on some platforms.
689 * </p>
690 *
691 * @param selection the new selection value
692 * @param minimum the new minimum value
693 * @param maximum the new maximum value
694 * @param thumb the new thumb value
695 * @param increment the new increment value
696 * @param pageIncrement the new pageIncrement value
697 *
698 * @exception SWTException <ul>
699 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
700 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
701 * </ul>
702 */
setValues(int selection, int minimum, int maximum, int thumb, int increment, int pageIncrement)703 public void setValues (int selection, int minimum, int maximum, int thumb, int increment, int pageIncrement) {
704 checkWidget();
705 if (minimum < 0) return;
706 if (maximum < 0) return;
707 if (thumb < 1) return;
708 if (increment < 1) return;
709 if (pageIncrement < 1) return;
710 this.thumb = thumb = Math.min (thumb, maximum - minimum);
711 this.maximum = maximum;
712 this.minimum = minimum;
713 this.increment = increment;
714 this.pageIncrement = pageIncrement;
715 updateBar (selection, minimum, maximum, thumb);
716 }
717
718 /**
719 * Marks the receiver as visible if the argument is <code>true</code>,
720 * and marks it invisible otherwise.
721 * <p>
722 * If one of the receiver's ancestors is not visible or some
723 * other condition makes the receiver not visible, marking
724 * it visible may not actually cause it to be displayed.
725 * </p>
726 *
727 * @param visible the new visibility state
728 *
729 * @exception SWTException <ul>
730 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
731 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
732 * </ul>
733 */
setVisible(boolean visible)734 public void setVisible (boolean visible) {
735 checkWidget();
736 parent.setScrollBarVisible (this, visible);
737 }
738
updateBar(int selection, int minimum, int maximum, int thumb)739 void updateBar (int selection, int minimum, int maximum, int thumb) {
740 NSScroller widget = (NSScroller) view;
741 selection = Math.max (minimum, Math.min (maximum - thumb, selection));
742 int range = maximum - thumb - minimum;
743 float fraction = range <= 0 ? 1 : (float) (selection - minimum) / range;
744 float knob = range <= 0 ? 1 : (float) thumb / (maximum - minimum);
745 double oldFraction = widget.doubleValue();
746 double oldKnob = widget.knobProportion();
747 widget.setDoubleValue(fraction);
748 widget.setKnobProportion(knob);
749 widget.setEnabled (range > 0);
750 if (target == null && (knob != oldKnob || fraction != oldFraction)) {
751 parent.scrollView.flashScrollers();
752 }
753 }
754
755 }
756