io.pelle.mango.client.gwt.MangoBootstrapLayoutFactory.java Source code

Java tutorial

Introduction

Here is the source code for io.pelle.mango.client.gwt.MangoBootstrapLayoutFactory.java

Source

/**
 * Copyright (c) 2013 Christian Pelster.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Christian Pelster - initial API and implementation
 */
package io.pelle.mango.client.gwt;

import io.pelle.mango.client.base.db.vos.UUID;
import io.pelle.mango.client.base.layout.ILayoutFactory;
import io.pelle.mango.client.base.layout.IModuleUI;
import io.pelle.mango.client.gwt.elements.ResizeColumn;
import io.pelle.mango.client.gwt.elements.ResizeContainer;
import io.pelle.mango.client.gwt.elements.ResizePanel;
import io.pelle.mango.client.gwt.elements.ResizePanelCollapse;
import io.pelle.mango.client.gwt.elements.ResizePanelGroup;
import io.pelle.mango.client.gwt.elements.ResizeRow;
import io.pelle.mango.client.gwt.modules.dictionary.editor.DictionaryEditorModuleUIFactory;
import io.pelle.mango.client.gwt.modules.dictionary.search.DictionarySearchModuleUIFactory;
import io.pelle.mango.client.gwt.modules.hierarchical.HierarchicalTreeModuleUIFactory;
import io.pelle.mango.client.gwt.modules.log.LogModuleUIFactory;
import io.pelle.mango.client.gwt.modules.navigation.NavigationModuleUIFactory;
import io.pelle.mango.client.gwt.modules.property.PropertyModuleUIFactory;
import io.pelle.mango.client.gwt.modules.webhook.WebhookModuleUIFactory;
import io.pelle.mango.client.web.module.ModuleUIFactoryRegistry;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import org.gwtbootstrap3.client.ui.Anchor;
import org.gwtbootstrap3.client.ui.Heading;
import org.gwtbootstrap3.client.ui.PanelGroup;
import org.gwtbootstrap3.client.ui.PanelHeader;
import org.gwtbootstrap3.client.ui.constants.ColumnSize;
import org.gwtbootstrap3.client.ui.constants.HeadingSize;
import org.gwtbootstrap3.client.ui.constants.PanelType;
import org.gwtbootstrap3.client.ui.constants.Toggle;

import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.DockLayoutPanel.Direction;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * {@link ILayoutFactory} implementation for GWT
 * 
 * @author pelle
 * 
 */
public class MangoBootstrapLayoutFactory implements ILayoutFactory<Panel, Widget> {

    public static final String ROOT_CONTAINER_CSS_ID = "mango-bootstrap-layout";

    public static final String CONTAINER_CSS_ID = "mango-bootstrap-layout-container";

    public static final String CONTAINER_MULTIPLE_CSS_ID = "mango-bootstrap-layout-multiple-container";

    final static Logger LOG = Logger.getLogger("MangoBootstrapLayoutFactory");

    private class PanelLayoutInfo {

        private final Widget widget;

        private List<IModuleUI<Panel, ?>> moduleUIs = new ArrayList<IModuleUI<Panel, ?>>();

        public PanelLayoutInfo(boolean supportsMultipleChildren, Widget widget) {
            super();
            this.widget = widget;
        }

        public List<IModuleUI<Panel, ?>> getModuleUIs() {
            return moduleUIs;
        }

        public boolean conainsModuleUI(IModuleUI<Panel, ?> moduleUI) {
            return moduleUIs.contains(moduleUI);
        }

        public void addModuleUI(IModuleUI<Panel, ?> moduleUI) {

            Panel moduleContainer = moduleUI.getContainer();
            moduleContainer.addStyleName(GwtStyles.MODULE);

            if (widget instanceof ResizePanelGroup) {

                String containerId = moduleUI.getModule().getModuleId();
                ResizePanelGroup panelGroup = (ResizePanelGroup) widget;
                ResizePanelCollapse panelCollapse = new ResizePanelCollapse();
                panelCollapse.setId(containerId);

                ResizePanel containerPanel = new ResizePanel(PanelType.DEFAULT);

                // create header
                PanelHeader panelHeader = new PanelHeader();
                Heading heading = new Heading(HeadingSize.H4);
                Anchor anchor = new Anchor();
                anchor.setText(moduleUI.getTitle());
                anchor.setDataTarget("#" + containerId);
                anchor.setDataParent("#" + panelGroup.getId());
                anchor.setDataToggle(Toggle.COLLAPSE);
                heading.add(anchor);
                panelHeader.add(heading);
                containerPanel.add(panelHeader);

                int beforeIndex = 0;

                List<IModuleUI<Panel, ?>> moduleUIs = panelGroupMappings.get(panelGroup);
                moduleUIs.add(moduleUI);

                Collections.sort(moduleUIs, new Comparator<IModuleUI<Panel, ?>>() {
                    @Override
                    public int compare(IModuleUI<Panel, ?> moduleUI1, IModuleUI<Panel, ?> moduleUI2) {
                        Integer order1 = moduleUI1.getOrder();
                        Integer order2 = moduleUI2.getOrder();
                        return order1.compareTo(order2);
                    }
                });
                beforeIndex = moduleUIs.indexOf(moduleUI);

                panelCollapse.add(moduleContainer);
                containerPanel.add(panelCollapse);

                panelGroup.insert(containerPanel, beforeIndex);

                panelCollapse.setIn(true);

            } else if (widget instanceof Panel) {
                Panel panel = (Panel) widget;
                removeAllChildren(panel);
                panel.add(moduleContainer);
            } else {
                throw new RuntimeException("unsupported panel type");
            }

            moduleUIs.add(moduleUI);

        }

        private void removeAllChildren(Panel panel) {
            Iterator<Widget> childrenIterator = panel.iterator();

            while (childrenIterator.hasNext()) {
                panel.remove(childrenIterator.next());
            }
        }

        public void removeModuleUI(IModuleUI<Panel, ?> moduleUI) {
            if (widget instanceof PanelGroup) {
                PanelGroup panelGroup = (PanelGroup) widget;
                panelGroup.remove(moduleUI.getContainer());
            } else if (widget instanceof Panel) {
                Panel panel = (Panel) widget;
                panel.remove(moduleUI.getContainer());
            } else {
                throw new RuntimeException("unsupported panel type");
            }
        }
    }

    private final Map<Direction, PanelLayoutInfo> containers = new HashMap<DockLayoutPanel.Direction, PanelLayoutInfo>();

    private final ResizeContainer rootContainer;

    /**
     * Constructor for {@link MangoBootstrapLayoutFactory}
     * 
     * @param unit
     */
    public MangoBootstrapLayoutFactory() {

        ModuleUIFactoryRegistry.getInstance().addModuleFactory(new NavigationModuleUIFactory());
        ModuleUIFactoryRegistry.getInstance().addModuleFactory(new DictionarySearchModuleUIFactory());
        ModuleUIFactoryRegistry.getInstance().addModuleFactory(new DictionaryEditorModuleUIFactory());
        ModuleUIFactoryRegistry.getInstance().addModuleFactory(new HierarchicalTreeModuleUIFactory());
        ModuleUIFactoryRegistry.getInstance().addModuleFactory(new LogModuleUIFactory());
        ModuleUIFactoryRegistry.getInstance().addModuleFactory(new WebhookModuleUIFactory());
        ModuleUIFactoryRegistry.getInstance().addModuleFactory(new PropertyModuleUIFactory());

        rootContainer = new ResizeContainer();
        rootContainer.setId(ROOT_CONTAINER_CSS_ID);
        rootContainer.setFluid(true);

        row = new ResizeRow();
        row.setHeight("100%");
        rootContainer.add(row);

        initializePanelLayout(Direction.WEST, true);
        initializePanelLayout(Direction.CENTER, false);

        RootLayoutPanel.get().add(rootContainer);

        Window.addResizeHandler(new ResizeHandler() {

            @Override
            public void onResize(ResizeEvent event) {

                for (Map.Entry<Direction, PanelLayoutInfo> panelEntry : containers.entrySet()) {
                    for (IModuleUI<Panel, ?> moduleUI : panelEntry.getValue().getModuleUIs()) {
                        moduleUI.onResize();
                    }
                }

            }
        });
    }

    private Map<ResizePanelGroup, List<IModuleUI<Panel, ?>>> panelGroupMappings = new HashMap<>();

    private ResizeRow row;

    private Direction getDirection(String location) {
        try {
            return Direction.valueOf(location);
        } catch (Exception e) {
            return Direction.CENTER;
        }
    }

    private void initializePanelLayout(Direction direction, boolean supportsMultipleChildren) {

        Panel container = null;

        switch (direction) {
        case CENTER:
            container = new ResizeColumn(ColumnSize.MD_10);
            break;
        case WEST:
            container = new ResizeColumn(ColumnSize.MD_2);
            break;
        default:
            throw new RuntimeException("unsupported direction '" + direction.toString() + "'");
        }

        container.getElement().setId(CONTAINER_CSS_ID + "-" + direction.toString().toLowerCase());
        container.setStyleName(CONTAINER_CSS_ID + "-" + direction.toString().toLowerCase(), true);
        container.setStyleName(CONTAINER_CSS_ID, true);
        container.setHeight("100%");

        row.add(container);

        if (supportsMultipleChildren) {
            ResizePanelGroup panelGroup = new ResizePanelGroup();
            panelGroup.setWidth("100%");
            panelGroup.setId(UUID.uuid());

            panelGroup.setStyleName(CONTAINER_MULTIPLE_CSS_ID, true);
            panelGroup.setStyleName(CONTAINER_CSS_ID, true);

            panelGroupMappings.put(panelGroup, new ArrayList<IModuleUI<Panel, ?>>());
            container.add(panelGroup);
            container = panelGroup;
        }

        containers.put(direction, new PanelLayoutInfo(supportsMultipleChildren, container));

    }

    private void showModuleUIInternal(IModuleUI<Panel, ?> moduleUI, DockLayoutPanel.Direction direction) {

        if (containers.containsKey(direction)) {
            PanelLayoutInfo panelLayoutInfo = containers.get(direction);
            panelLayoutInfo.addModuleUI(moduleUI);
        } else {
            throw new RuntimeException("no panel layout info found for direction '" + direction + "'");
        }

    }

    /** {@inheritDoc} */
    @Override
    public void showModuleUI(IModuleUI<Panel, ?> moduleUI, String location) {
        LOG.info("showing module ui '" + moduleUI + "' for location '" + location + "'");

        DockLayoutPanel.Direction direction = getDirection(location);

        showModuleUIInternal(moduleUI, direction);
    }

    private Direction getDirection(IModuleUI<Panel, ?> moduleUI) {
        for (Map.Entry<Direction, PanelLayoutInfo> panelEntry : containers.entrySet()) {
            if (panelEntry.getValue().conainsModuleUI(moduleUI)) {
                return panelEntry.getKey();
            }
        }

        throw new RuntimeException("no direction found for module ui '" + moduleUI + "'");

    }

    @Override
    public void closeModuleUI(IModuleUI<Panel, ?> moduleUI) {

        LOG.info("closing module ui '" + moduleUI.getModule().getModuleUrl() + "'");

        Direction direction = getDirection(moduleUI);

        if (containers.containsKey(direction)) {
            PanelLayoutInfo panelLayoutInfo = containers.get(direction);
            panelLayoutInfo.removeModuleUI(moduleUI);
        } else {
            throw new RuntimeException("no panel layout info found for direction '" + direction + "'");
        }
    }

}