1/*
2 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package sun.awt.windows;
26
27import java.awt.*;
28import java.awt.peer.*;
29import java.awt.event.AdjustmentEvent;
30
31final class WScrollbarPeer extends WComponentPeer implements ScrollbarPeer {
32
33    // Returns width for vertial scrollbar as SM_CXHSCROLL,
34    // height for horizontal scrollbar as SM_CYVSCROLL
35    static native int getScrollbarSize(int orientation);
36
37    // ComponentPeer overrides
38    public Dimension getMinimumSize() {
39        if (((Scrollbar)target).getOrientation() == Scrollbar.VERTICAL) {
40            return new Dimension(getScrollbarSize(Scrollbar.VERTICAL), 50);
41        }
42        else {
43            return new Dimension(50, getScrollbarSize(Scrollbar.HORIZONTAL));
44        }
45    }
46
47    // ScrollbarPeer implementation
48
49    public native void setValues(int value, int visible,
50                                 int minimum, int maximum);
51    public native void setLineIncrement(int l);
52    public native void setPageIncrement(int l);
53
54
55    // Toolkit & peer internals
56
57    WScrollbarPeer(Scrollbar target) {
58        super(target);
59    }
60
61    native void create(WComponentPeer parent);
62
63    void initialize() {
64        Scrollbar sb = (Scrollbar)target;
65        setValues(sb.getValue(), sb.getVisibleAmount(),
66                  sb.getMinimum(), sb.getMaximum());
67        super.initialize();
68    }
69
70
71    // NOTE: Callback methods are called by privileged threads.
72    //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
73
74    private void postAdjustmentEvent(final int type, final int value,
75                                     final boolean isAdjusting)
76    {
77        final Scrollbar sb = (Scrollbar)target;
78        WToolkit.executeOnEventHandlerThread(sb, new Runnable() {
79            public void run() {
80                sb.setValueIsAdjusting(isAdjusting);
81                sb.setValue(value);
82                postEvent(new AdjustmentEvent(sb,
83                                AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
84                                type, value, isAdjusting));
85            }
86        });
87    }
88
89    void lineUp(int value) {
90        postAdjustmentEvent(AdjustmentEvent.UNIT_DECREMENT, value, false);
91    }
92
93    void lineDown(int value) {
94        postAdjustmentEvent(AdjustmentEvent.UNIT_INCREMENT, value, false);
95    }
96
97    void pageUp(int value) {
98        postAdjustmentEvent(AdjustmentEvent.BLOCK_DECREMENT, value, false);
99    }
100
101    void pageDown(int value) {
102        postAdjustmentEvent(AdjustmentEvent.BLOCK_INCREMENT, value, false);
103    }
104
105    // SB_TOP/BOTTOM are mapped to tracking
106    void warp(int value) {
107        postAdjustmentEvent(AdjustmentEvent.TRACK, value, false);
108    }
109
110    private boolean dragInProgress = false;
111
112    void drag(final int value) {
113        if (!dragInProgress) {
114            dragInProgress = true;
115        }
116        postAdjustmentEvent(AdjustmentEvent.TRACK, value, true);
117    }
118
119    void dragEnd(final int value) {
120        final Scrollbar sb = (Scrollbar)target;
121
122        if (!dragInProgress) {
123            return;
124        }
125
126        dragInProgress = false;
127        WToolkit.executeOnEventHandlerThread(sb, new Runnable() {
128            public void run() {
129                // NB: notification only, no sb.setValue()
130                // last TRACK event will have done it already
131                sb.setValueIsAdjusting(false);
132                postEvent(new AdjustmentEvent(sb,
133                                AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
134                                AdjustmentEvent.TRACK, value, false));
135            }
136        });
137    }
138
139    public boolean shouldClearRectBeforePaint() {
140        return false;
141    }
142}
143