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 & Co. KG (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.CmsContainerpageDNDController;
import org.opencms.ade.containerpage.client.ui.css.I_CmsLayoutBundle;
import org.opencms.ade.containerpage.shared.CmsContainer;
import org.opencms.gwt.client.dnd.CmsDNDHandler.Orientation;
import org.opencms.gwt.client.dnd.I_CmsDraggable;
import org.opencms.gwt.client.dnd.I_CmsDropTarget;
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 org.opencms.util.CmsStringUtil;

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.Display;
import com.google.gwt.dom.client.Style.Position;
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; /** Flag indicating if the given element is visible. */ private boolean m_isVisible; /** * 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_isVisible = !Display.NONE.getCssName().equals(m_element.getStyle().getDisplay()); if (m_isVisible) { m_elementPosition = CmsPositionBean.getBoundingClientRect(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); } /** * Returns if the given element is visible.

* * @return true if the given element is visible */ public boolean isVisible() { return m_isVisible; } } /** Name of a special property for the container id. */ public static final String PROP_CONTAINER_MARKER = "opencmsContainerId"; /** The container level. */ private int m_containerLevel; /** The container data. */ private CmsContainer m_containerData; /** The list of nested sub containers that are also valid drop targets during the current drag and drop. */ private List m_dnDChildren; /** The element position info cache. */ private List m_elementPositions; /** The element to display in case the container is empty. */ private Element m_emptyContainerElement; /** Highlighting border for this container. */ private CmsHighlightingBorder m_highlighting; /** 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 current place holder visibility. */ private boolean m_placeholderVisible; /** Flag indicating the element positions need to be re-evaluated. */ private boolean m_requiresPositionUpdate = true; /** * Constructor.

* * @param containerData the container data * @param element the container element */ public CmsContainerPageContainer(CmsContainer containerData, Element element) { setElement(element); if (!containerData.isSubContainer()) { RootPanel.detachOnWindowClose(this); } m_containerData = containerData; element.setPropertyString(PROP_CONTAINER_MARKER, containerData.getName()); addStyleName(I_CmsLayoutBundle.INSTANCE.dragdropCss().dragTarget()); onAttach(); } /** * @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#addDndChild(org.opencms.gwt.client.dnd.I_CmsDropTarget) */ public void addDndChild(I_CmsDropTarget child) { if (m_dnDChildren == null) { m_dnDChildren = new ArrayList(); } m_dnDChildren.add(child); } /** * @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); } /** * Check if the empty container content should be displayed or removed.

*/ public void checkEmptyContainers() { if (getWidgetCount() == 0) { if (m_emptyContainerElement != null) { m_emptyContainerElement.getStyle().clearDisplay(); } else if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_containerData.getEmptyContainerContent())) { // add empty container element try { m_emptyContainerElement = CmsDomUtil.createElement(m_containerData.getEmptyContainerContent()); getElement().appendChild(m_emptyContainerElement); } catch (Exception e) { CmsDebugLog.getInstance().printLine(e.getMessage()); } } } else if (m_emptyContainerElement != null) { m_emptyContainerElement.removeFromParent(); m_emptyContainerElement = null; } } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#checkMaxElementsOnEnter() */ public void checkMaxElementsOnEnter() { int count = getWidgetCount(); if (count >= m_containerData.getMaxElements()) { 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_containerData.getMaxElements()) { if (overflowElement == null) { overflowElement = widget; } } } } if (overflowElement != null) { m_overflowingElement = overflowElement; m_overflowingElement.removeFromParent(); } } if (count == 0) { if (m_emptyContainerElement != null) { m_emptyContainerElement.getStyle().setDisplay(Display.NONE); } } } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#checkMaxElementsOnLeave() */ public void checkMaxElementsOnLeave() { if (m_overflowingElement != null) { add(m_overflowingElement); } if (m_emptyContainerElement != null) { m_emptyContainerElement.getStyle().clearDisplay(); } } /** * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#checkPosition(int, int, Orientation) */ public boolean checkPosition(int x, int y, Orientation orientation) { if (m_ownPosition != null) { // 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; } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#clearDnDChildren() */ public void clearDnDChildren() { if (m_dnDChildren != null) { m_dnDChildren.clear(); } } /** * 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_containerData.getWidth(); } /** * Returns the container id.

* * @return the container id */ public String getContainerId() { return m_containerData.getName(); } /** * Returns the container level.

* * @return the container level */ public int getContainerLevel() { return m_containerLevel; } /** * Returns the container type.

* * @return the container type */ public String getContainerType() { return m_containerData.getType(); } /** * In case of a former copy model, and a max elements setting of one, the id of the overflowing element is returned.

* * @return the overflowing element id or null */ public String getCopyModelReplaceId() { String result = null; if ((m_containerData.getMaxElements() == 1) && (m_overflowingElement != null) && (m_overflowingElement instanceof CmsContainerPageElementPanel) && (getFormerModelGroupParent() != null)) { result = ((CmsContainerPageElementPanel)m_overflowingElement).getId(); } return result; } /** * @see org.opencms.gwt.client.dnd.I_CmsNestedDropTarget#getDnDChildren() */ public List getDnDChildren() { return m_dnDChildren; } /** * Returns whether this container has a model group parent.

* * @return true if this container has a model group parent */ public Element getFormerModelGroupParent() { Element result = null; Element parent = getElement().getParentElement(); while (parent != null) { if (parent.getPropertyBoolean(CmsContainerPageElementPanel.PROP_WAS_MODEL_GROUP)) { result = parent; break; } parent = parent.getParentElement(); } return result; } /** * Returns the parent container id.

* * @return the container parent id */ public String getParentContainerId() { return m_containerData.getParentContainerName(); } /** * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#getPlaceholderIndex() */ public int getPlaceholderIndex() { return m_placeholderIndex; } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#getPositionInfo() */ public CmsPositionBean getPositionInfo() { return m_ownPosition; } /** * @see org.opencms.gwt.client.dnd.I_CmsNestedDropTarget#hasDnDChildren() */ public boolean hasDnDChildren() { return (m_dnDChildren != null) && !m_dnDChildren.isEmpty(); } /** * Returns whether this container has a model group parent.

* * @return true if this container has a model group parent */ public boolean hasModelGroupParent() { boolean result = false; Element parent = getElement().getParentElement(); while (parent != null) { if (parent.getPropertyBoolean(CmsContainerPageElementPanel.PROP_IS_MODEL_GROUP)) { result = true; break; } parent = parent.getParentElement(); } return result; } /** * @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() { highlightContainer(CmsPositionBean.getBoundingClientRect(getElement())); } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#highlightContainer(org.opencms.gwt.client.util.CmsPositionBean) */ public void highlightContainer(CmsPositionBean positionInfo) { // remove any remaining highlighting if (m_highlighting != null) { m_highlighting.removeFromParent(); } // cache the position info, to be used during drag and drop m_ownPosition = positionInfo; m_highlighting = new CmsHighlightingBorder( m_ownPosition, CmsHighlightingBorder.BorderColor.red, CmsContainerpageDNDController.HIGHLIGHTING_OFFSET); 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_placeholderVisible = false; m_placeholder.getStyle().setDisplay(Display.NONE); m_requiresPositionUpdate = true; repositionPlaceholder(x, y, orientation); } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#isDetailOnly() */ public boolean isDetailOnly() { return m_containerData.isDetailOnly(); } /** * Returns true if this is a detail view container.

* * @return true if this is a detail view container */ public boolean isDetailView() { return m_containerData.isDetailView(); } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#isEditable() */ public boolean isEditable() { return m_containerData.isEditable(); } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#onConsumeChildren(java.util.List) */ public void onConsumeChildren(List children) { // nothing to do } /** * @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) { refreshHighlighting(CmsPositionBean.getBoundingClientRect(getElement())); } } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#refreshHighlighting(org.opencms.gwt.client.util.CmsPositionBean) */ public void refreshHighlighting(CmsPositionBean positionInfo) { // cache the position info, to be used during drag and drop m_ownPosition = positionInfo; if (m_highlighting != null) { m_highlighting.setPosition(m_ownPosition); } } /** * Removes the highlighting border.

*/ public void removeHighlighting() { if (m_highlighting != null) { m_highlighting.removeFromParent(); m_highlighting = null; } } /** * @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; // check if the empty container content should be displayed or removed checkEmptyContainers(); } /** * @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; } /** * Sets the container level.

* * @param level the container level */ public void setContainerLevel(int level) { m_containerLevel = level; } /** * Sets the empty container element.

* * @param emptyContainerElement the empty container element */ public void setEmptyContainerElement(Element emptyContainerElement) { m_emptyContainerElement = emptyContainerElement; } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#setPlaceholderVisibility(boolean) */ public void setPlaceholderVisibility(boolean visible) { if (m_placeholderVisible != visible) { m_placeholderVisible = visible; m_requiresPositionUpdate = true; if (m_placeholderVisible) { m_placeholder.getStyle().clearDisplay(); } else { m_placeholder.getStyle().setDisplay(Display.NONE); } } } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#showEditableListButtons() */ public void showEditableListButtons() { for (Widget child : this) { 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(); } } } /** * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#updatePositionInfo() */ public void updatePositionInfo() { m_ownPosition = CmsPositionBean.getBoundingClientRect(getElement()); } /** * 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() || !info.isVisible()) { 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.getBoundingClientRect(getElement()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy