001: /*
002: * @(#)QtScrollPanePeer.java 1.22 06/10/20
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027: package sun.awt.qt;
028:
029: import java.awt.*;
030: import java.awt.event.AdjustmentEvent;
031: import sun.awt.peer.*;
032:
033: /**
034: *
035: *
036: * @author Nicholas Allen
037: */
038: class QtScrollPanePeer extends QtContainerPeer implements
039: ScrollPanePeer {
040: private static native void initIDs();
041:
042: private static int hScrollbarHeight = calculateHScrollbarHeight();
043: private static int vScrollbarWidth = calculateVScrollbarWidth();
044:
045: private static native int calculateHScrollbarHeight();
046:
047: private static native int calculateVScrollbarWidth();
048:
049: private native void enableScrollbarsNative(boolean hBarOn,
050: boolean vBarOn);
051:
052: private boolean ignoreSetValue;
053:
054: private int scrollbarDisplayPolicy;
055:
056: public Dimension getPreferredSize() {
057: return target.getSize();
058: }
059:
060: static {
061: initIDs();
062: }
063:
064: /** Creates a new QtScrollPanePeer. */
065:
066: QtScrollPanePeer(QtToolkit toolkit, ScrollPane target) {
067: super (toolkit, target);
068: scrollbarDisplayPolicy = target.getScrollbarDisplayPolicy();
069: }
070:
071: protected native void create(QtComponentPeer parentPeer);
072:
073: native void add(QtComponentPeer peer);
074:
075: void remove(QtComponentPeer peer) {
076: updateScrollBarsNative(); //6249842
077: }
078:
079: /** Overridden to calculate insets. This includes any optional
080: scrollbars so we need to dynamically work this out. */
081:
082: public Insets getInsets() {
083:
084: // adjust predicted view size to account for scrollbars
085:
086: // This accounts for the 2 pixels from the edge of the viewport
087: // to the edge of the scrollview on qt-emb-2.3.2.
088: Insets insets = new Insets(2, 2, 2, 2);
089:
090: // 6347067.
091: // TCK: ScrollPane test failed when waiting time is added after the validate().
092: // Fixed 6228838: Resizing the panel cause wrong scroll bar range
093: // on zaurus, which, in turn, fixed the viewport size problem in
094: // CDC 1.1 linux-x86. But zaurus still has a problem which is shown when
095: // running the PP-TCK interactive ComponetTests where two tests will have
096: // both scroll bars on and in these two tests, you can see that the
097: // bottom of the "Yes" "No" buttons are chopped off.
098: //
099: // The getInsets() call is modified to calculate whether scrollbars are on
100: // in order to return the correct insets. In particular,
101: //
102: // Given that the hScrollbarHeight and vScrollbarWidth are known, which
103: // is true in the Qt port case:
104: //
105: // hScrollbarOn is a function of scrollpane dim, child dim, as well as
106: // vScrollbarOn in the boundary case where the horizontal scrollbar could
107: // be needed if the vertical scrollbar needs to be present and the extra
108: // width due to the vertical scrollbar just makes the horizontal
109: // scrollbar necessary!
110:
111: ScrollPane sp = (ScrollPane) target;
112: Dimension d = sp.size();
113: Component c = getScrollChild();
114: Dimension cd;
115: if (c != null) {
116: cd = c.size();
117: } else {
118: cd = new Dimension(0, 0);
119: }
120:
121: if (scrollbarDisplayPolicy == ScrollPane.SCROLLBARS_ALWAYS) {
122: insets.right += vScrollbarWidth;
123: insets.bottom += hScrollbarHeight;
124: } else if (scrollbarDisplayPolicy == ScrollPane.SCROLLBARS_AS_NEEDED) {
125: if (d.width - insets.left * 2 < cd.width) {
126: // Hbar is necessary.
127: insets.bottom += hScrollbarHeight;
128: if (d.height - insets.top - insets.bottom < cd.height) {
129: insets.right += vScrollbarWidth;
130: }
131: } else if (d.width - insets.left * 2 - cd.width >= vScrollbarWidth) {
132: // We're very sure that hbar will not be on.
133: if (d.height - insets.top * 2 < cd.height) {
134: insets.right += vScrollbarWidth;
135: }
136: } else {
137: // Borderline case so we need to check vbar first.
138: if (d.height - insets.top * 2 < cd.height) {
139: insets.right += vScrollbarWidth;
140: if (d.width - insets.left - insets.right < cd.width) {
141: // Hbar is needed after all!
142: insets.bottom += hScrollbarHeight;
143: }
144: }
145: }
146: }
147: // 6347067.
148:
149: return insets;
150: }
151:
152: public int getHScrollbarHeight() {
153: return hScrollbarHeight;
154: }
155:
156: public int getVScrollbarWidth() {
157: return vScrollbarWidth;
158: }
159:
160: public void childResized(int w, int h) {
161:
162: // Compensates forthe setBounds() call in ScrollPane.layout() because in
163: // the native layer, the child component is reparented to the viewport
164: // rather than to the scrollview widget.
165: Component c = ((Container) target).getComponent(0);
166: c.setLocation(c.getX() - 2, c.getY() - 2);
167:
168: if (scrollbarDisplayPolicy == ScrollPane.SCROLLBARS_AS_NEEDED) {
169: childResizedNative(w, h); // 6228838
170: }
171:
172: // Removed the scrollbar workaround for gtk.
173: }
174:
175: public void setUnitIncrement(Adjustable adj, int u) {
176: setUnitIncrementNative(adj.getOrientation(), u);
177: }
178:
179: private native void setUnitIncrementNative(int orientation,
180: int increment);
181:
182: //6255265
183: public int setValue(Adjustable adj, int v) {
184: if (ignoreSetValue)
185: return -1; //6255265
186:
187: int orientation = adj.getOrientation();
188: int max = adj.getMaximum();
189: int pageSize = adj.getVisibleAmount();
190:
191: int rval = setAdjusterNative(orientation, v, max, pageSize); //6255265
192: return rval;
193: }
194:
195: class QtScrollPaneAdjustableEvent extends AWTEvent implements
196: ActiveEvent {
197: QtScrollPanePeer peer;
198: Adjustable adjuster;
199: int value;
200:
201: QtScrollPaneAdjustableEvent(QtScrollPanePeer src,
202: Adjustable adj, int val) {
203: super (src, 0);
204: peer = src;
205: adjuster = adj;
206: value = val;
207: }
208:
209: public void dispatch() {
210: // Fixed 6260600.
211: // Qt can emit the valueChanged signals for horizontal or vertical
212: // scroll bars after scroll child removal as a result of the call
213: // made to updateScrollBarsNative. If there is no scroll child,
214: // it is not necessary to update the Adjustable for the current
215: // value.
216: // See also 6249842.
217: if (getScrollChild() == null) {
218: return;
219: }
220:
221: peer.ignoreSetValue = true;
222: adjuster.setValue(value);
223: peer.ignoreSetValue = false;
224: }
225: }
226:
227: // Fixed 6260600.
228: private Component getScrollChild() {
229: ScrollPane sp = (ScrollPane) target;
230: Component child = null;
231: try {
232: child = sp.getComponent(0);
233: } catch (ArrayIndexOutOfBoundsException e) {
234: // do nothing. in this case we return null
235: }
236: return child;
237: }
238:
239: // Fixed 6260600.
240:
241: private void postAdjustableEvent(int orientation, int value) {
242: if (orientation == Adjustable.HORIZONTAL) {
243: QtToolkit.postEvent(new QtScrollPaneAdjustableEvent(this ,
244: ((ScrollPane) target).getHAdjustable(), value));
245: } else if (orientation == Adjustable.VERTICAL) {
246: QtToolkit.postEvent(new QtScrollPaneAdjustableEvent(this ,
247: ((ScrollPane) target).getVAdjustable(), value));
248: }
249: }
250:
251: private native int setAdjusterNative(int orientation, int value,
252: int max, int pageSize); //6255265
253:
254: private native boolean scrollbarVisible(int orientation);
255:
256: private native void updateScrollBarsNative(); //6249842
257:
258: private native void childResizedNative(int width, int height); // 6228838
259: }
|