/* * @(#)QtScrollPanePeer.java 1.22 06/10/20 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */ package sun.awt.qt; import java.awt.*; import java.awt.event.AdjustmentEvent; import sun.awt.peer.*; /** * * * @author Nicholas Allen */ class QtScrollPanePeer extends QtContainerPeer implements ScrollPanePeer { private static native void initIDs(); private static int hScrollbarHeight = calculateHScrollbarHeight(); private static int vScrollbarWidth = calculateVScrollbarWidth(); private static native int calculateHScrollbarHeight(); private static native int calculateVScrollbarWidth(); private native void enableScrollbarsNative(boolean hBarOn, boolean vBarOn); private boolean ignoreSetValue; private int scrollbarDisplayPolicy; public Dimension getPreferredSize() { return target.getSize(); } static { initIDs(); } /** Creates a new QtScrollPanePeer. */ QtScrollPanePeer (QtToolkit toolkit, ScrollPane target) { super (toolkit, target); scrollbarDisplayPolicy = target.getScrollbarDisplayPolicy(); } protected native void create(QtComponentPeer parentPeer); native void add (QtComponentPeer peer); void remove(QtComponentPeer peer) { updateScrollBarsNative(); //6249842 } /** Overridden to calculate insets. This includes any optional scrollbars so we need to dynamically work this out. */ public Insets getInsets() { // adjust predicted view size to account for scrollbars // This accounts for the 2 pixels from the edge of the viewport // to the edge of the scrollview on qt-emb-2.3.2. Insets insets = new Insets(2, 2, 2, 2); // 6347067. // TCK: ScrollPane test failed when waiting time is added after the validate(). // Fixed 6228838: Resizing the panel cause wrong scroll bar range // on zaurus, which, in turn, fixed the viewport size problem in // CDC 1.1 linux-x86. But zaurus still has a problem which is shown when // running the PP-TCK interactive ComponetTests where two tests will have // both scroll bars on and in these two tests, you can see that the // bottom of the "Yes" "No" buttons are chopped off. // // The getInsets() call is modified to calculate whether scrollbars are on // in order to return the correct insets. In particular, // // Given that the hScrollbarHeight and vScrollbarWidth are known, which // is true in the Qt port case: // // hScrollbarOn is a function of scrollpane dim, child dim, as well as // vScrollbarOn in the boundary case where the horizontal scrollbar could // be needed if the vertical scrollbar needs to be present and the extra // width due to the vertical scrollbar just makes the horizontal // scrollbar necessary! ScrollPane sp = (ScrollPane)target; Dimension d = sp.size(); Component c = getScrollChild(); Dimension cd; if (c != null) { cd = c.size(); } else { cd = new Dimension(0, 0); } if (scrollbarDisplayPolicy == ScrollPane.SCROLLBARS_ALWAYS) { insets.right += vScrollbarWidth; insets.bottom += hScrollbarHeight; } else if (scrollbarDisplayPolicy == ScrollPane.SCROLLBARS_AS_NEEDED) { if (d.width - insets.left*2 < cd.width) { // Hbar is necessary. insets.bottom += hScrollbarHeight; if (d.height - insets.top - insets.bottom < cd.height) { insets.right += vScrollbarWidth; } } else if (d.width - insets.left*2 - cd.width >= vScrollbarWidth) { // We're very sure that hbar will not be on. if (d.height - insets.top*2 < cd.height) { insets.right += vScrollbarWidth; } } else { // Borderline case so we need to check vbar first. if (d.height - insets.top*2 < cd.height) { insets.right += vScrollbarWidth; if (d.width - insets.left - insets.right < cd.width) { // Hbar is needed after all! insets.bottom += hScrollbarHeight; } } } } // 6347067. return insets; } public int getHScrollbarHeight() { return hScrollbarHeight; } public int getVScrollbarWidth() { return vScrollbarWidth; } public void childResized(int w, int h) { // Compensates forthe setBounds() call in ScrollPane.layout() because in // the native layer, the child component is reparented to the viewport // rather than to the scrollview widget. Component c = ((Container)target).getComponent(0); c.setLocation(c.getX() - 2, c.getY() - 2); if(scrollbarDisplayPolicy == ScrollPane.SCROLLBARS_AS_NEEDED) { childResizedNative(w, h); // 6228838 } // Removed the scrollbar workaround for gtk. } public void setUnitIncrement(Adjustable adj, int u) { setUnitIncrementNative(adj.getOrientation(), u); } private native void setUnitIncrementNative(int orientation, int increment); //6255265 public int setValue(Adjustable adj, int v) { if(ignoreSetValue) return -1; //6255265 int orientation = adj.getOrientation(); int max = adj.getMaximum(); int pageSize = adj.getVisibleAmount(); int rval = setAdjusterNative(orientation, v, max, pageSize); //6255265 return rval; } class QtScrollPaneAdjustableEvent extends AWTEvent implements ActiveEvent { QtScrollPanePeer peer; Adjustable adjuster; int value; QtScrollPaneAdjustableEvent(QtScrollPanePeer src, Adjustable adj, int val) { super(src, 0); peer = src; adjuster = adj; value = val; } public void dispatch() { // Fixed 6260600. // Qt can emit the valueChanged signals for horizontal or vertical // scroll bars after scroll child removal as a result of the call // made to updateScrollBarsNative. If there is no scroll child, // it is not necessary to update the Adjustable for the current // value. // See also 6249842. if (getScrollChild() == null) { return; } peer.ignoreSetValue = true; adjuster.setValue(value); peer.ignoreSetValue = false; } } // Fixed 6260600. private Component getScrollChild() { ScrollPane sp = (ScrollPane)target; Component child = null; try { child = sp.getComponent(0); } catch (ArrayIndexOutOfBoundsException e) { // do nothing. in this case we return null } return child; } // Fixed 6260600. private void postAdjustableEvent(int orientation, int value) { if (orientation == Adjustable.HORIZONTAL) { QtToolkit.postEvent(new QtScrollPaneAdjustableEvent(this, ((ScrollPane)target).getHAdjustable(), value)); } else if (orientation == Adjustable.VERTICAL) { QtToolkit.postEvent(new QtScrollPaneAdjustableEvent(this, ((ScrollPane)target).getVAdjustable(), value)); } } private native int setAdjusterNative(int orientation, int value, int max, int pageSize); //6255265 private native boolean scrollbarVisible(int orientation); private native void updateScrollBarsNative(); //6249842 private native void childResizedNative(int width, int height); // 6228838 }