All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.gwt.client.ui.CmsScrollPanelImpl Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 18.0
Show newest version
/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.gwt.client.ui;

import com.alkacon.geranium.client.I_DescendantResizeHandler;

import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle;
import org.opencms.gwt.client.util.CmsDomUtil;
import org.opencms.gwt.client.util.CmsDomUtil.Style;
import org.opencms.gwt.client.util.CmsFadeAnimation;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.AbstractNativeScrollbar;
import com.google.gwt.user.client.ui.VerticalScrollbar;
import com.google.gwt.user.client.ui.Widget;

/**
 * Scroll panel implementation with custom scroll bars. Works in all browsers but IE7.

*/ public class CmsScrollPanelImpl extends CmsScrollPanel { /** * Handler to show and hide the scroll bar on hover.

*/ private class HoverHandler implements MouseOutHandler, MouseOverHandler { /** The owner element. */ Element m_owner; /** The element to fade in and out. */ private Element m_fadeElement; /** The currently running hide animation. */ private CmsFadeAnimation m_hideAnimation; /** The timer to hide the scroll bar with a delay. */ private Timer m_removeTimer; /** * Constructor.

* * @param owner the owner element * @param fadeElement the element to fade in and out on hover */ HoverHandler(Element owner, Element fadeElement) { m_owner = owner; m_fadeElement = fadeElement; } /** * @see com.google.gwt.event.dom.client.MouseOutHandler#onMouseOut(com.google.gwt.event.dom.client.MouseOutEvent) */ public void onMouseOut(MouseOutEvent event) { m_removeTimer = new Timer() { /** * @see com.google.gwt.user.client.Timer#run() */ @Override public void run() { clearShowing(); } }; m_removeTimer.schedule(1000); } /** * @see com.google.gwt.event.dom.client.MouseOverHandler#onMouseOver(com.google.gwt.event.dom.client.MouseOverEvent) */ public void onMouseOver(MouseOverEvent event) { if ((m_hideAnimation != null) || !CmsDomUtil.hasClass(I_CmsLayoutBundle.INSTANCE.scrollBarCss().showBars(), m_owner)) { if (m_hideAnimation != null) { m_hideAnimation.cancel(); m_hideAnimation = null; } else { CmsFadeAnimation.fadeIn(m_fadeElement, null, 100); } m_owner.addClassName(I_CmsLayoutBundle.INSTANCE.scrollBarCss().showBars()); } if (m_removeTimer != null) { m_removeTimer.cancel(); m_removeTimer = null; } } /** * Hides the scroll bar.

*/ void clearShowing() { m_hideAnimation = CmsFadeAnimation.fadeOut(m_fadeElement, new Command() { public void execute() { m_owner.removeClassName(I_CmsLayoutBundle.INSTANCE.scrollBarCss().showBars()); } }, 200); m_removeTimer = null; } } /** Hidden element to measure the appropriate size of the container element. */ private Element m_hiddenSize; /** The measured width of the native scroll bars. */ private int m_nativeScrollbarWidth; /** The vertical scroll bar. */ private VerticalScrollbar m_scrollbar; /** The scroll layer. */ private Element m_scrollLayer; /** The scroll bar change handler registration. */ private HandlerRegistration m_verticalScrollbarHandlerRegistration; /** The scroll bar width. */ private int m_verticalScrollbarWidth; /** * Constructor.

*/ public CmsScrollPanelImpl() { super(DOM.createDiv(), DOM.createDiv(), DOM.createDiv()); setStyleName(I_CmsLayoutBundle.INSTANCE.scrollBarCss().scrollPanel()); Element scrollable = getScrollableElement(); scrollable.getStyle().clearPosition(); scrollable.setClassName(I_CmsLayoutBundle.INSTANCE.scrollBarCss().scrollable()); getElement().appendChild(scrollable); Element container = getContainerElement(); container.setClassName(I_CmsLayoutBundle.INSTANCE.scrollBarCss().scrollContainer()); scrollable.appendChild(container); m_scrollLayer = DOM.createDiv(); getElement().appendChild(m_scrollLayer); m_scrollLayer.setClassName(I_CmsLayoutBundle.INSTANCE.scrollBarCss().scrollbarLayer()); CmsScrollBar scrollbar = new CmsScrollBar(scrollable, container); setVerticalScrollbar(scrollbar, 8); m_hiddenSize = DOM.createDiv(); m_hiddenSize.setClassName(I_CmsLayoutBundle.INSTANCE.scrollBarCss().hiddenSize()); /* * Listen for scroll events from the root element and the scrollable element * so we can align the scrollbars with the content. Scroll events usually * come from the scrollable element, but they can also come from the root * element if the user clicks and drags the content, which reveals the * hidden scrollbars. */ Event.sinkEvents(getElement(), Event.ONSCROLL); Event.sinkEvents(scrollable, Event.ONSCROLL); initHoverHandler(); } /** * @see com.google.gwt.user.client.ui.SimplePanel#iterator() */ @Override public Iterator iterator() { // Return a simple iterator that enumerates the 0 or 1 elements in this // panel. List widgets = new ArrayList(); if (getWidget() != null) { widgets.add(getWidget()); } if (getVerticalScrollBar() != null) { widgets.add(getVerticalScrollBar().asWidget()); } final Iterator internalIterator = widgets.iterator(); return new Iterator() { public boolean hasNext() { return internalIterator.hasNext(); } public Widget next() { return internalIterator.next(); } public void remove() { throw new UnsupportedOperationException(); } }; } /** * @see com.google.gwt.user.client.ui.Widget#onBrowserEvent(com.google.gwt.user.client.Event) */ @Override public void onBrowserEvent(Event event) { // Align the scrollbars with the content. if (Event.ONSCROLL == event.getTypeInt()) { maybeUpdateScrollbarPositions(); } super.onBrowserEvent(event); } /** * @see com.alkacon.geranium.client.I_DescendantResizeHandler#onResizeDescendant() */ @Override public void onResizeDescendant() { int maxHeight = CmsDomUtil.getCurrentStyleInt(getElement(), Style.maxHeight); if (maxHeight > 0) { getScrollableElement().getStyle().setPropertyPx("maxHeight", maxHeight); } // appending div to measure panel width, doing it every time anew to avoid rendering bugs in Chrome getElement().appendChild(m_hiddenSize); int width = m_hiddenSize.getClientWidth(); m_hiddenSize.removeFromParent(); if (width > 0) { getContainerElement().getStyle().setWidth(width, Unit.PX); maybeUpdateScrollbars(); } } /** * @see org.opencms.gwt.client.ui.CmsScrollPanel#setResizable(boolean) */ @Override public void setResizable(boolean resize) { super.setResizable(resize); if (resize) { m_scrollbar.asWidget().getElement().getStyle().setMarginBottom(7, Unit.PX); } else { m_scrollbar.asWidget().getElement().getStyle().setMarginBottom(0, Unit.PX); } } /** * Returns the vertical scroll bar.

* * @return the vertical scroll bar */ protected VerticalScrollbar getVerticalScrollBar() { return m_scrollbar; } /** * @see com.google.gwt.user.client.ui.ScrollPanel#onAttach() */ @Override protected void onAttach() { super.onAttach(); hideNativeScrollbars(); onResizeDescendant(); } /** * @see com.google.gwt.user.client.ui.Widget#onLoad() */ @Override protected void onLoad() { super.onLoad(); hideNativeScrollbars(); Scheduler.get().scheduleDeferred(new ScheduledCommand() { public void execute() { onResizeDescendant(); } }); } /** * Hide the native scrollbars. We call this after attaching to ensure that we * inherit the direction (rtl or ltr). */ private void hideNativeScrollbars() { m_nativeScrollbarWidth = AbstractNativeScrollbar.getNativeScrollbarWidth(); getScrollableElement().getStyle().setMarginRight(-(m_nativeScrollbarWidth + 10), Unit.PX); } /** * Initializes the hover handler to hide and show the scroll bar on hover.

*/ private void initHoverHandler() { HoverHandler handler = new HoverHandler(getElement(), m_scrollbar.asWidget().getElement()); addDomHandler(handler, MouseOverEvent.getType()); addDomHandler(handler, MouseOutEvent.getType()); } /** * Synchronize the scroll positions of the scrollbars with the actual scroll * position of the content. */ private void maybeUpdateScrollbarPositions() { if (!isAttached()) { return; } if (m_scrollbar != null) { int vPos = getVerticalScrollPosition(); if (m_scrollbar.getVerticalScrollPosition() != vPos) { m_scrollbar.setVerticalScrollPosition(vPos); } } } /** * Update the position of the scrollbars.

* If only the vertical scrollbar is present, it takes up the entire height of * the right side. If only the horizontal scrollbar is present, it takes up * the entire width of the bottom. If both scrollbars are present, the * vertical scrollbar extends from the top to just above the horizontal * scrollbar, and the horizontal scrollbar extends from the left to just right * of the vertical scrollbar, leaving a small square in the bottom right * corner.

*/ private void maybeUpdateScrollbars() { if (!isAttached()) { return; } /* * Measure the height and width of the content directly. Note that measuring * the height and width of the container element (which should be the same) * doesn't work correctly in IE. */ Widget w = getWidget(); int contentHeight = (w == null) ? 0 : w.getOffsetHeight(); // Determine which scrollbars to show. int realScrollbarHeight = 0; int realScrollbarWidth = 0; if ((m_scrollbar != null) && (getElement().getClientHeight() < contentHeight)) { // Vertical scrollbar is defined and required. realScrollbarWidth = m_verticalScrollbarWidth; } if (realScrollbarWidth > 0) { m_scrollLayer.getStyle().clearDisplay(); m_scrollbar.setScrollHeight(Math.max(0, contentHeight - realScrollbarHeight)); } else if (m_scrollLayer != null) { m_scrollLayer.getStyle().setDisplay(Display.NONE); } if (m_scrollbar instanceof I_DescendantResizeHandler) { ((I_DescendantResizeHandler)m_scrollbar).onResizeDescendant(); } maybeUpdateScrollbarPositions(); } /** * Set the scrollbar used for vertical scrolling. * * @param scrollbar the scrollbar, or null to clear it * @param width the width of the scrollbar in pixels */ private void setVerticalScrollbar(final CmsScrollBar scrollbar, int width) { // Validate. if ((scrollbar == m_scrollbar) || (scrollbar == null)) { return; } // Detach new child. scrollbar.asWidget().removeFromParent(); // Remove old child. if (m_scrollbar != null) { if (m_verticalScrollbarHandlerRegistration != null) { m_verticalScrollbarHandlerRegistration.removeHandler(); m_verticalScrollbarHandlerRegistration = null; } remove(m_scrollbar); } m_scrollLayer.appendChild(scrollbar.asWidget().getElement()); adopt(scrollbar.asWidget()); // Logical attach. m_scrollbar = scrollbar; m_verticalScrollbarWidth = width; // Initialize the new scrollbar. m_verticalScrollbarHandlerRegistration = scrollbar.addValueChangeHandler(new ValueChangeHandler() { public void onValueChange(ValueChangeEvent event) { int vPos = scrollbar.getVerticalScrollPosition(); int v = getVerticalScrollPosition(); if (v != vPos) { setVerticalScrollPosition(vPos); } } }); maybeUpdateScrollbars(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy