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

com.gwtplatform.mvp.client.view.RelativeToWidgetPopupPositioner Maven / Gradle / Ivy

There is a newer version: 1.6
Show newest version
/**
 * Copyright 2014 ArcBees Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.gwtplatform.mvp.client.view;

import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;

/**
 *  Positions the popup relative to a widget.
 */
public class RelativeToWidgetPopupPositioner extends PopupPositioner {
    private final Widget widget;
    private final boolean clipToWindow;

    /**
     * @param widget - the widget relative to which the popup will be shown.
     * 
     * If there is enough space to the right, the left edge of the popup will be positioned flush with
     * the left edge of the widget.

*

     *     --------
     *     |widget|
     *     -------------
     *     |popup panel|
     *     -------------
     * 
* * Otherwise if there is enough space on the left the right edge of the popup will be positioned * flush with the right edge of the widget.

*

     *          --------
     *          |widget|
     *     -------------
     *     |popup panel|
     *     -------------
     * 
* * If there is not enough space to the left or the right and clipToWindow is on. The popup will be * positioned on the left edge of the screen.

*

     *      |   --------
     *      |   |widget|
     *      |-------------
     *      ||popup panel|
     *      |-------------
     * 
* * If you would prefer the popupPanel to always be flush with the widget call * {@link #RelativeToWidgetPopupPositioner(IsWidget, boolean)} * and set clipToWindow to false */ public RelativeToWidgetPopupPositioner(IsWidget widget) { this(widget, true); } /** * @param widget - the widget relative to which the popup will be shown. * @param clipToWindow - set to false to always position the popup flush to an edge of the widget. * * If there is enough space to the right, the left edge of the popup will be positioned flush with * the left edge of the widget.

*

     *     --------
     *     |widget|
     *     -------------
     *     |popup panel|
     *     -------------
     * 
* * Otherwise if there is enough space on the left the right edge of the popup will be positioned * flush with the right edge of the widget.

*

     *          --------
     *          |widget|
     *     -------------
     *     |popup panel|
     *     -------------
     * 
* * If there is not enough space to the left or the right and clipToWindow is on. The popup will be * positioned on the left edge of the screen.

*

     *      |   --------
     *      |   |widget|
     *      |-------------
     *      ||popup panel|
     *      |-------------
     * 
* * Set clipToWindow to false to always position the popup flush to an edge of the widget and expand * the screen when it will not fit. */ public RelativeToWidgetPopupPositioner(IsWidget widget, boolean clipToWindow) { this.widget = widget.asWidget(); this.clipToWindow = clipToWindow; } @Override protected int getTop(int popupHeight) { int top = widget.getAbsoluteTop(); int windowTop = Window.getScrollTop(); int windowBottom = Window.getScrollTop() + Window.getClientHeight(); int distanceFromWindowTop = top - windowTop; int distanceToWindowBottom = windowBottom - (top + widget.getOffsetHeight()); if (distanceToWindowBottom < popupHeight && distanceFromWindowTop >= popupHeight) { top -= popupHeight; } else { top += widget.getOffsetHeight(); } return top; } @Override protected int getLeft(int popupWidth) { return LocaleInfo.getCurrentLocale().isRTL() ? getRtlLeft(popupWidth) : getLtrLeft(popupWidth); } protected int getLtrLeft(int popupWidth) { if (!canFitOnLeftEdge(popupWidth) && (canFitOnRightEdge(popupWidth) || clipToWindow)) { return Math.max(0, getRightEdge(popupWidth)); } else { return widget.getAbsoluteLeft(); } } protected int getRtlLeft(int popupWidth) { if (!canFitOnRightEdge(popupWidth) && (canFitOnLeftEdge(popupWidth) || !clipToWindow)) { return widget.getAbsoluteLeft(); } else { return Math.max(0, getRightEdge(popupWidth)); } } private int getRightEdge(int popupWidth) { return widget.getAbsoluteLeft() + widget.getOffsetWidth() - popupWidth; } private boolean canFitOnLeftEdge(int popupWidth) { int windowRight = Window.getClientWidth() + Window.getScrollLeft(); return windowRight - popupWidth > widget.getAbsoluteLeft(); } private boolean canFitOnRightEdge(int popupWidth) { return getRightEdge(popupWidth) >= Window.getScrollLeft(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy