com.servoy.j2db.server.headlessclient.dataui.WebAnchoringHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.servoy.j2db.server.headlessclient.dataui.WebAnchoringHelper.java

Source

/*
 This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2012 Servoy BV
    
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU Affero General Public License as published by the Free
 Software Foundation; either version 3 of the License, or (at your option) any
 later version.
    
 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 Affero General Public License for more details.
    
 You should have received a copy of the GNU Affero General Public License along
 with this program; if not, see http://www.gnu.org/licenses or write to the Free
 Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 */

package com.servoy.j2db.server.headlessclient.dataui;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.Hashtable;
import java.util.Properties;

import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.model.AbstractReadOnlyModel;

import com.servoy.j2db.IServiceProvider;
import com.servoy.j2db.component.ComponentFactory;
import com.servoy.j2db.persistence.Field;
import com.servoy.j2db.persistence.IAnchorConstants;
import com.servoy.j2db.persistence.IFormElement;
import com.servoy.j2db.persistence.ISupportAnchors;
import com.servoy.j2db.server.headlessclient.WrapperContainer;
import com.servoy.j2db.ui.ISupportWebBounds;
import com.servoy.j2db.util.Utils;

/**
 * Helper class for web anchoring
 * @author gboros
 */
public class WebAnchoringHelper {

    public static Component getWrapperComponent(Component comp, IFormElement obj, int start, Dimension panelSize,
            boolean leftToRight, boolean isInListView) {
        MarkupContainer compWrapper = new WrapperContainer(
                ComponentFactory.getWebID(null, obj) + TemplateGenerator.WRAPPER_SUFFIX, comp);
        Point l = (obj).getLocation();
        if (isInListView) {
            // substract left indicator
            l.x = Math.max(l.x - 3, 0);
        }
        Dimension s = (obj).getSize();
        int anchors = 0;
        if (obj instanceof ISupportAnchors)
            anchors = ((ISupportAnchors) obj).getAnchors();
        int offsetWidth = s.width;
        int offsetHeight = s.height;
        if (comp instanceof ISupportWebBounds) {
            Rectangle b = ((ISupportWebBounds) comp).getWebBounds();
            offsetWidth = b.width;
            offsetHeight = b.height;
        }
        final String styleToReturn = WebAnchoringHelper.computeWrapperDivStyle(l.y, l.x, offsetWidth, offsetHeight,
                s.width, s.height, anchors, start, start + panelSize.height, panelSize.width, leftToRight);
        // first the default
        compWrapper.add(new StyleAppendingModifier(new AbstractReadOnlyModel<String>() {
            @Override
            public String getObject() {
                return styleToReturn;
            }
        }));
        // then the style t hat can be set on the wrapped component
        compWrapper.add(StyleAttributeModifierModel.INSTANCE);
        // TODO: this needs to be done in a cleaner way. See what is the relation between
        // margin, padding and border when calculating the websize in ChangesRecorder vs. TemplateGenerator.
        // Looks like one of the three is not taken into account during calculations. For now decided to remove
        // the margin and leave the padding and border.
        comp.add(new StyleAppendingModifier(new AbstractReadOnlyModel<String>() {
            @Override
            public String getObject() {
                return "margin: 0px;"; //$NON-NLS-1$
            }
        }));
        return compWrapper;
    }

    public static boolean needsWrapperDivForAnchoring(Field field) {
        // this needs to be in sync with DesignModeBehavior.needsWrapperDivForAnchoring(String type)
        return (field.getDisplayType() == Field.PASSWORD) || (field.getDisplayType() == Field.TEXT_AREA)
                || (field.getDisplayType() == Field.COMBOBOX) || (field.getDisplayType() == Field.TYPE_AHEAD)
                || (field.getDisplayType() == Field.TEXT_FIELD) || (field.getDisplayType() == Field.LIST_BOX)
                || (field.getDisplayType() == Field.MULTISELECT_LISTBOX)
                || (field.getDisplayType() == Field.HTML_AREA && field.getEditable());
    }

    private static String computeWrapperDivStyle(int top, int left, int width, int height, int offsetWidth,
            int offsetHeight, int anchorFlags, int partStartY, int partEndY, int partWidth, boolean leftToRight) {
        Hashtable<String, String> style = new Hashtable<String, String>();
        if (top != -1)
            style.put("top", top + "px"); //$NON-NLS-1$ //$NON-NLS-2$
        if (left != -1)
            style.put("left", left + "px"); //$NON-NLS-1$ //$NON-NLS-2$
        if (width != -1)
            style.put("width", width + "px"); //$NON-NLS-1$ //$NON-NLS-2$
        if (height != -1)
            style.put("height", height + "px"); //$NON-NLS-1$ //$NON-NLS-2$

        boolean anchoredTop = (anchorFlags & IAnchorConstants.NORTH) != 0;
        boolean anchoredRight = (anchorFlags & IAnchorConstants.EAST) != 0;
        boolean anchoredBottom = (anchorFlags & IAnchorConstants.SOUTH) != 0;
        boolean anchoredLeft = (anchorFlags & IAnchorConstants.WEST) != 0;

        if (!anchoredLeft && !anchoredRight)
            anchoredLeft = true;
        if (!anchoredTop && !anchoredBottom)
            anchoredTop = true;

        int deltaLeft = leftToRight ? 0 : offsetWidth - width;
        int deltaRight = leftToRight ? offsetWidth - width : 0;
        int deltaBottom = offsetHeight - height;

        if (anchoredTop)
            style.put("top", (top - partStartY) + "px"); //$NON-NLS-1$ //$NON-NLS-2$
        else
            style.remove("top"); //$NON-NLS-1$
        if (anchoredBottom)
            style.put("bottom", (partEndY - top - offsetHeight + deltaBottom) + "px"); //$NON-NLS-1$ //$NON-NLS-2$
        if (!anchoredTop || !anchoredBottom)
            style.put("height", height + "px"); //$NON-NLS-1$ //$NON-NLS-2$
        else
            style.remove("height"); //$NON-NLS-1$
        if (anchoredLeft)
            style.put("left", (left + deltaLeft) + "px"); //$NON-NLS-1$ //$NON-NLS-2$
        else
            style.remove("left"); //$NON-NLS-1$
        if (anchoredRight)
            style.put("right", (partWidth - left - offsetWidth + deltaRight) + "px"); //$NON-NLS-1$ //$NON-NLS-2$
        if (!anchoredLeft || !anchoredRight)
            style.put("width", width + "px"); //$NON-NLS-1$ //$NON-NLS-2$
        else
            style.remove("width"); //$NON-NLS-1$
        style.put("position", "absolute"); //$NON-NLS-1$ //$NON-NLS-2$
        if (width != -1)
            style.put("min-width", width + "px"); //$NON-NLS-1$ //$NON-NLS-2$

        StringBuffer sb = new StringBuffer();
        for (String key : style.keySet()) {
            String value = style.get(key);
            sb.append(key);
            sb.append(": "); //$NON-NLS-1$
            sb.append(value);
            sb.append("; "); //$NON-NLS-1$
        }
        return sb.toString();
    }

    public static void addMinSize(int anchors, IServiceProvider application, Properties cssProperties,
            Dimension size, IFormElement formElement) {
        if (size != null
                && (application == null
                        || Utils.getAsBoolean(application.getRuntimeProperties().get("enableAnchors")))
                && !TemplateGenerator.isTableViewComponent(formElement)) {
            if (((anchors & IAnchorConstants.EAST) > 0) && ((anchors & IAnchorConstants.WEST) > 0)) {
                cssProperties.setProperty("min-width", size.width + "px");
            }
            if (((anchors & IAnchorConstants.NORTH) > 0) && ((anchors & IAnchorConstants.SOUTH) > 0)
                    && size != null) {
                cssProperties.setProperty("min-height", size.height + "px");
            }
        }
    }
}