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

org.opencms.ade.containerpage.client.ui.CmsContainerPageContainer 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.ade.containerpage.client.ui;

import org.opencms.ade.containerpage.client.ui.css.I_CmsLayoutBundle;
import org.opencms.ade.containerpage.shared.I_CmsContainer;
import org.opencms.gwt.client.dnd.CmsDNDHandler.Orientation;
import org.opencms.gwt.client.dnd.I_CmsDraggable;
import org.opencms.gwt.client.ui.CmsHighlightingBorder;
import org.opencms.gwt.client.util.CmsDebugLog;
import org.opencms.gwt.client.util.CmsDomUtil;
import org.opencms.gwt.client.util.CmsDomUtil.Style;
import org.opencms.gwt.client.util.CmsPositionBean;
import org.opencms.gwt.shared.CmsTemplateContextInfo;

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

import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * Container page container.

* * * * @since 8.0.0 */ public class CmsContainerPageContainer extends ComplexPanel implements I_CmsDropContainer { /** * Element position info class.

*/ protected class ElementPositionInfo { /** The DOM element. */ private Element m_element; /** The element position bean. */ private CmsPositionBean m_elementPosition; /** The float CSS property. */ private String m_float; /** Flag indicating the element is positioned absolute. */ private boolean m_isAbsolute; /** * Constructor.

* * @param element the DOM element */ public ElementPositionInfo(Element element) { m_element = element; String positioning = CmsDomUtil.getCurrentStyle(m_element, Style.position); m_isAbsolute = Position.ABSOLUTE.getCssName().equals(positioning) || Position.FIXED.getCssName().equals(positioning); if (!m_isAbsolute) { m_elementPosition = CmsPositionBean.getInnerDimensions(element); m_float = CmsDomUtil.getCurrentStyle(m_element, Style.floatCss); } } /** * Returns the DOM element.

* * @return the DOM element */ public Element getElement() { return m_element; } /** * Returns the element position bean.

* * @return the element position bean */ public CmsPositionBean getElementPosition() { return m_elementPosition; } /** * Returns the x distance of the cursor to the element left.

* * @param x the cursor x position * @param documentScrollLeft the document scroll left position * * @return the y distance of the cursor to the element top */ public int getRelativeLeft(int x, int documentScrollLeft) { return (x + documentScrollLeft) - m_elementPosition.getLeft(); } /** * Returns the y distance of the cursor to the element top.

* * @param y the cursor y position * @param documentScrollTop the document scroll top position * * @return the y distance of the cursor to the element top */ public int getRelativeTop(int y, int documentScrollTop) { return (y + documentScrollTop) - m_elementPosition.getTop(); } /** * Returns if the element is positioned absolute.

* * @return true if the element is positioned absolute */ public boolean isAbsolute() { return m_isAbsolute; } /** * Returns if the element is floated.

* * @return true if the element is floated */ public boolean isFloating() { return isFloatLeft() || isFloatRight(); } /** * Returns if the element is floated to the left.

* * @return true if the element is floated to the left */ public boolean isFloatLeft() { return "left".equals(m_float); } /** * Returns if the element is floated to the right.

* * @return true if the element is floated to the right */ public boolean isFloatRight() { return "right".equals(m_float); } } /** Flag indicating if this container is a detail view only container. */ boolean m_detailOnly; /** The configured width for this container. */ private int m_configuredWidth; /** Container element id. */ private String m_containerId; /** The container type. */ private String m_containerType; /** The element position info cache. */ private List m_elementPositions; /** Highlighting border for this container. */ private CmsHighlightingBorder m_highlighting; /** True if this is a detail view container. */ private boolean m_isDetailView; /** The maximum number of elements in this container. */ private int m_maxElements; /** The overflowing element. */ private Widget m_overflowingElement; /** The cached highlighting position. */ private CmsPositionBean m_ownPosition; /** The drag and drop placeholder. */ private Element m_placeholder; /** The drag and drop placeholder position index. */ private int m_placeholderIndex = -1; /** Flag indicating the element positions need to be re-evaluated. */ private boolean m_requiresPositionUpdate = true; /** The wrapped widget. This will be a @link com.google.gwt.user.client.RootPanel. */ private Widget m_widget; /** * Constructor.

* * @param containerData the container data */ public CmsContainerPageContainer(I_CmsContainer containerData) { initWidget(RootPanel.get(containerData.getName())); m_containerId = containerData.getName(); m_containerType = containerData.getType(); m_maxElements = containerData.getMaxElements(); m_isDetailView = containerData.isDetailView(); m_detailOnly = containerData.isDetailOnly(); m_configuredWidth = containerData.getWidth(); addStyleName(I_CmsLayoutBundle.INSTANCE.dragdropCss().dragTarget()); } /** * @see com.google.gwt.user.client.ui.Panel#add(com.google.gwt.user.client.ui.Widget) */ @Override public void add(Widget w) { add(w, (Element)getElement()); } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#adoptElement(org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel) */ public void adoptElement(CmsContainerPageElementPanel containerElement) { assert getElement().equals(containerElement.getElement().getParentElement()); getChildren().add(containerElement); adopt(containerElement); } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#checkMaxElementsOnEnter() */ public void checkMaxElementsOnEnter() { if (getWidgetCount() >= m_maxElements) { Widget overflowElement = null; int index = 0; for (Widget widget : this) { boolean isDummy = widget.getStyleName().contains(CmsTemplateContextInfo.DUMMY_ELEMENT_MARKER); if (!isDummy) { index++; if (index >= m_maxElements) { if (overflowElement == null) { overflowElement = widget; } } } } if (overflowElement != null) { m_overflowingElement = overflowElement; m_overflowingElement.removeFromParent(); } } } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#checkMaxElementsOnLeave() */ public void checkMaxElementsOnLeave() { if (m_overflowingElement != null) { add(m_overflowingElement); } } /** * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#checkPosition(int, int, Orientation) */ public boolean checkPosition(int x, int y, Orientation orientation) { // ignore orientation int scrollTop = getElement().getOwnerDocument().getScrollTop(); // use cached position int relativeTop = (y + scrollTop) - m_ownPosition.getTop(); if ((relativeTop > 0) && (m_ownPosition.getHeight() > relativeTop)) { // cursor is inside the height of the element, check horizontal position int scrollLeft = getElement().getOwnerDocument().getScrollLeft(); int relativeLeft = (x + scrollLeft) - m_ownPosition.getLeft(); return (relativeLeft > 0) && (m_ownPosition.getWidth() > relativeLeft); } return false; } /** * Returns all contained drag elements.

* * @return the drag elements */ public List getAllDragElements() { List elements = new ArrayList(); Iterator it = iterator(); while (it.hasNext()) { Widget w = it.next(); if (w instanceof CmsContainerPageElementPanel) { elements.add((CmsContainerPageElementPanel)w); } else { if (CmsDomUtil.hasClass( org.opencms.ade.containerpage.client.ui.css.I_CmsLayoutBundle.INSTANCE.containerpageCss().groupcontainerPlaceholder(), w.getElement())) { CmsDebugLog.getInstance().printLine("Ignoring group container placeholder."); } else { CmsDebugLog.getInstance().printLine( "WARNING: " + w.toString() + " is no instance of CmsDragContainerElement"); } } } return elements; } /** * Returns the configured width for this container.

* * @return the configured width */ public int getConfiguredWidth() { return m_configuredWidth; } /** * Returns the container id.

* * @return the container id */ public String getContainerId() { return m_containerId; } /** * Returns the container type.

* * @return the container type */ public String getContainerType() { return m_containerType; } /** * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#getPlaceholderIndex() */ public int getPlaceholderIndex() { return m_placeholderIndex; } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#hideEditableListButtons() */ public void hideEditableListButtons() { Iterator it = iterator(); while (it.hasNext()) { Widget child = it.next(); if (child instanceof CmsContainerPageElementPanel) { ((CmsContainerPageElementPanel)child).hideEditableListButtons(); } } } /** * Puts a highlighting border around the container content.

*/ public void highlightContainer() { getElement().addClassName(I_CmsLayoutBundle.INSTANCE.dragdropCss().dragging()); // remove any remaining highlighting if (m_highlighting != null) { m_highlighting.removeFromParent(); } // adding the 'clearFix' style to all targets containing floated elements // in some layouts this may lead to inappropriate clearing after the target, // but it is still necessary as it forces the target to enclose it's floated content if ((getWidgetCount() > 0) && !CmsDomUtil.getCurrentStyle(getWidget(0).getElement(), CmsDomUtil.Style.floatCss).equals( CmsDomUtil.StyleValue.none.toString())) { getElement().addClassName(I_CmsLayoutBundle.INSTANCE.dragdropCss().clearFix()); } // cache the position info, to be used during drag and drop m_ownPosition = CmsPositionBean.getInnerDimensions(getElement(), 3, false); m_highlighting = new CmsHighlightingBorder(m_ownPosition, CmsHighlightingBorder.BorderColor.red); RootPanel.get().add(m_highlighting); } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#insert(com.google.gwt.user.client.ui.Widget, int) */ public void insert(Widget w, int beforeIndex) { insert(w, (Element)getElement(), beforeIndex, true); } /** * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#insertPlaceholder(com.google.gwt.dom.client.Element, int, int, Orientation) */ public void insertPlaceholder(Element placeholder, int x, int y, Orientation orientation) { m_placeholder = placeholder; m_requiresPositionUpdate = true; repositionPlaceholder(x, y, orientation); } /** * @see com.google.gwt.user.client.ui.Widget#isAttached() */ @Override public boolean isAttached() { if (m_widget != null) { return m_widget.isAttached(); } return false; } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#isDetailOnly() */ public boolean isDetailOnly() { return m_detailOnly; } /** * Returns true if this is a detail view container.

* * @return true if this is a detail view container */ public boolean isDetailView() { return m_isDetailView; } /** * @see com.google.gwt.user.client.ui.Widget#onBrowserEvent(com.google.gwt.user.client.Event) */ @Override public void onBrowserEvent(Event event) { // Fire any handler added to the composite itself. super.onBrowserEvent(event); // Delegate events to the widget. m_widget.onBrowserEvent(event); } /** * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#onDrop(org.opencms.gwt.client.dnd.I_CmsDraggable) */ public void onDrop(I_CmsDraggable draggable) { m_overflowingElement = null; } /** * Refreshes position and dimension of the highlighting border. Call when anything changed during the drag process.

*/ public void refreshHighlighting() { if (m_highlighting != null) { // cache the position info, to be used during drag and drop m_ownPosition = CmsPositionBean.getInnerDimensions(getElement(), 3, false); m_highlighting.setPosition(m_ownPosition); } } /** * Removes the highlighting border.

*/ public void removeHighlighting() { if (m_highlighting != null) { m_highlighting.removeFromParent(); m_highlighting = null; } removeStyleName(I_CmsLayoutBundle.INSTANCE.dragdropCss().dragging()); removeStyleName(I_CmsLayoutBundle.INSTANCE.dragdropCss().clearFix()); } /** * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#removePlaceholder() */ public void removePlaceholder() { if (m_placeholder != null) { m_placeholder.removeFromParent(); m_placeholder = null; } m_placeholderIndex = -1; m_requiresPositionUpdate = true; } /** * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#repositionPlaceholder(int, int, Orientation) */ public void repositionPlaceholder(int x, int y, Orientation orientation) { if (m_requiresPositionUpdate) { updatePositionsList(); } int newPlaceholderIndex = internalRepositionPlaceholder(x, y); m_requiresPositionUpdate = newPlaceholderIndex != m_placeholderIndex; m_placeholderIndex = newPlaceholderIndex; } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#showEditableListButtons() */ public void showEditableListButtons() { Iterator it = iterator(); while (it.hasNext()) { Widget child = it.next(); if (child instanceof CmsContainerPageElementPanel) { ((CmsContainerPageElementPanel)child).showEditableListButtons(); } } } /** * Updates the option bar positions of the child elements.

*/ public void updateOptionBars() { for (Widget widget : this) { if (widget instanceof CmsContainerPageElementPanel) { ((CmsContainerPageElementPanel)widget).updateOptionBarPosition(); } } } /** * Provides subclasses access to the topmost widget that defines this * composite. * * @return the widget */ protected Widget getWidget() { return m_widget; } /** * Sets the widget to be wrapped by the composite. The wrapped widget must be * set before calling any {@link Widget} methods on this object, or adding it * to a panel. This method may only be called once for a given composite. * * @param widget the widget to be wrapped */ protected void initWidget(Widget widget) { // Validate. Make sure the widget is not being set twice. if (m_widget != null) { throw new IllegalStateException("Composite.initWidget() may only be " + "called once."); } // Use the contained widget's element as the composite's element, // effectively merging them within the DOM. setElement((Element)widget.getElement()); adopt(widget); // Logical attach. m_widget = widget; } /** * Repositions the drag and drop placeholder.

* * @param x the x cursor position * @param y the y cursor position * * @return the placeholder position index */ private int internalRepositionPlaceholder(int x, int y) { int indexCorrection = 0; int previousTop = 0; int documentScrollTop = getElement().getOwnerDocument().getScrollTop(); int documentScrollLeft = getElement().getOwnerDocument().getScrollLeft(); for (int index = 0; index < m_elementPositions.size(); index++) { ElementPositionInfo info = m_elementPositions.get(index); if (info.getElement() == m_placeholder) { indexCorrection = 1; } if (info.isAbsolute()) { continue; } int top = info.getRelativeTop(y, documentScrollTop); if ((top <= 0) || (top >= info.getElementPosition().getHeight())) { previousTop = top; continue; } int left = info.getRelativeLeft(x, documentScrollLeft); if ((left <= 0) || (left >= info.getElementPosition().getWidth())) { previousTop = top; continue; } boolean floatSort = info.isFloating() && (top != 0) && (top == previousTop); previousTop = top; if (info.getElement() != m_placeholder) { if (floatSort) { boolean insertBefore = false; if (left < (info.getElementPosition().getWidth() / 2)) { if (info.isFloatLeft()) { insertBefore = true; } } else if (info.isFloatRight()) { insertBefore = true; } if (insertBefore) { getElement().insertBefore(m_placeholder, info.getElement()); return index - indexCorrection; } else { getElement().insertAfter(m_placeholder, info.getElement()); return (index + 1) - indexCorrection; } } else { if (top < (info.getElementPosition().getHeight() / 2)) { getElement().insertBefore(m_placeholder, info.getElement()); return index - indexCorrection; } else { getElement().insertAfter(m_placeholder, info.getElement()); return (index + 1) - indexCorrection; } } } else { return index; } } // not over any child position if ((m_placeholderIndex >= 0) && (m_placeholder.getParentElement() == getElement())) { // element is already attached to this parent and no new position available // don't do anything return m_placeholderIndex; } int top = CmsDomUtil.getRelativeY(y, getElement()); int offsetHeight = getElement().getOffsetHeight(); if ((top >= (offsetHeight / 2))) { // over top half, insert as first child getElement().insertFirst(m_placeholder); return 0; } // over bottom half, insert as last child getElement().appendChild(m_placeholder); return getElement().getChildCount() - 1; } /** * Updates the element position cache during drag and drop.

*/ private void updatePositionsList() { CmsDebugLog.getInstance().printLine("Updating positions"); if (m_elementPositions != null) { m_elementPositions.clear(); } else { m_elementPositions = new ArrayList(); } for (int index = 0; index < getElement().getChildCount(); index++) { Node node = getElement().getChild(index); if (node.getNodeType() != Node.ELEMENT_NODE) { continue; } m_elementPositions.add(new ElementPositionInfo((Element)node)); } m_requiresPositionUpdate = false; m_ownPosition = CmsPositionBean.getInnerDimensions(getElement(), 3, false); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy