Package org.thechiselgroup.choosel.core.client.visualization

Source Code of org.thechiselgroup.choosel.core.client.visualization.DefaultView$ViewPanel

/*******************************************************************************
* Copyright 2009, 2010 Lars Grammel
*
* 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 org.thechiselgroup.choosel.core.client.visualization;

import org.thechiselgroup.choosel.core.client.error_handling.ErrorHandler;
import org.thechiselgroup.choosel.core.client.persistence.Memento;
import org.thechiselgroup.choosel.core.client.persistence.Persistable;
import org.thechiselgroup.choosel.core.client.persistence.PersistableRestorationService;
import org.thechiselgroup.choosel.core.client.resources.ResourceByPropertyMultiCategorizer;
import org.thechiselgroup.choosel.core.client.resources.ResourceByUriMultiCategorizer;
import org.thechiselgroup.choosel.core.client.resources.ResourceMultiCategorizer;
import org.thechiselgroup.choosel.core.client.resources.persistence.ResourceSetAccessor;
import org.thechiselgroup.choosel.core.client.resources.persistence.ResourceSetCollector;
import org.thechiselgroup.choosel.core.client.ui.ImageButton;
import org.thechiselgroup.choosel.core.client.ui.Presenter;
import org.thechiselgroup.choosel.core.client.ui.SidePanelSection;
import org.thechiselgroup.choosel.core.client.util.DisposeUtil;
import org.thechiselgroup.choosel.core.client.util.NoSuchAdapterException;
import org.thechiselgroup.choosel.core.client.util.collections.LightweightCollection;
import org.thechiselgroup.choosel.core.client.visualization.model.ViewContentDisplay;
import org.thechiselgroup.choosel.core.client.visualization.model.VisualizationModel;
import org.thechiselgroup.choosel.core.client.visualization.model.extensions.ResourceModel;
import org.thechiselgroup.choosel.core.client.visualization.model.extensions.SelectionModel;
import org.thechiselgroup.choosel.core.client.visualization.model.managed.ManagedSlotMappingConfiguration;
import org.thechiselgroup.choosel.core.client.visualization.model.persistence.ManagedSlotMappingConfigurationPersistence;
import org.thechiselgroup.choosel.core.client.visualization.ui.VisualMappingsControl;
import org.thechiselgroup.choosel.core.shared.util.ForTest;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.StackPanel;
import com.google.gwt.user.client.ui.Widget;

public class DefaultView implements View {

    private class ViewPanel extends DockPanel implements ViewProvider {

        /**
         * Enables finding this view by searching the widget hierarchy.
         */
        @Override
        public View get() {
            return DefaultView.this;
        }

        @Override
        protected void onDetach() {
            dispose();
            super.onDetach();
        }

        /*
         * Fixes bug that map is not resized if window is resized
         */
        @Override
        public void setPixelSize(int width, int height) {
            DefaultView.this.setSize(width, height);
            super.setPixelSize(width, height);
        }

    }

    private static final String MEMENTO_LABEL_KEY = "label";

    private static final String CSS_EXPANDER = "DefaultView-Expander";

    private static final String CSS_CONFIGURATION_PANEL = "DefaultView-ConfigurationPanel";

    private static final String CSS_VIEW_CONFIGURATION_PANEL = "view-configurationPanel";

    // TODO rename
    private DockPanel configurationBar;

    // TODO rename
    private StackPanel sideBar;

    /**
     * The main panel of this view. It contains all other widgets of this view.
     */
    private ViewPanel viewPanel;

    private Presenter resourceModelPresenter;

    private Presenter selectionModelPresenter;

    private int width;

    private int height;

    /**
     * Sections that will be displayed in the side panel. This is a lightweight
     * collections so we can check whether it is empty or not.
     */
    private LightweightCollection<SidePanelSection> sidePanelSections;

    private ViewContentDisplay contentDisplay;

    private VisualizationModel visualizationModel;

    private ResourceModel resourceModel;

    private SelectionModel selectionModel;

    private boolean isInitialized;

    private String contentType;

    private ErrorHandler errorHandler;

    private String label;

    private ManagedSlotMappingConfigurationPersistence managedSlotMappingConfigurationPersistence;

    private ManagedSlotMappingConfiguration managedSlotMappingConfiguration;

    private static final String MEMENTO_CONTENT_DISPLAY = "content-display";

    private static final String MEMENTO_RESOURCE_MODEL = "resource-model";

    private static final String MEMENTO_SELECTION_MODEL = "selection-model";

    private static final String MEMENTO_SLOT_MAPPINGS = "slot-mappings";

    private static final String MEMENTO_GROUPING = "grouping";

    // TODO change parameter order in constructor
    // TODO change contentDisplay to more restricted interface
    public DefaultView(
            ViewContentDisplay contentDisplay,
            String label,
            String contentType,
            Presenter selectionModelPresenter,
            Presenter resourceModelPresenter,
            VisualMappingsControl visualMappingsControl,
            LightweightCollection<SidePanelSection> sidePanelSections,
            VisualizationModel visualizationModel,
            ResourceModel resourceModel,
            SelectionModel selectionModel,
            ManagedSlotMappingConfiguration managedSlotMappingConfiguration,
            ManagedSlotMappingConfigurationPersistence managedSlotMappingConfigurationPersistence,
            ErrorHandler errorHandler) {

        assert label != null;
        assert contentType != null;
        assert contentDisplay != null;
        assert selectionModelPresenter != null;
        assert resourceModelPresenter != null;
        assert sidePanelSections != null;
        assert visualizationModel != null;
        assert resourceModel != null;
        assert selectionModel != null;
        assert managedSlotMappingConfiguration != null;
        assert managedSlotMappingConfigurationPersistence != null;
        assert errorHandler != null;

        this.label = label;
        this.contentType = contentType;
        this.contentDisplay = contentDisplay;
        this.selectionModelPresenter = selectionModelPresenter;
        this.resourceModelPresenter = resourceModelPresenter;
        this.sidePanelSections = sidePanelSections;
        this.visualizationModel = visualizationModel;
        this.selectionModel = selectionModel;
        this.resourceModel = resourceModel;
        this.managedSlotMappingConfiguration = managedSlotMappingConfiguration;
        this.managedSlotMappingConfigurationPersistence = managedSlotMappingConfigurationPersistence;
        this.errorHandler = errorHandler;
    }

    @Override
    public <T> T adaptTo(Class<T> clazz) throws NoSuchAdapterException {
        return contentDisplay.adaptTo(clazz);
    }

    @Override
    public Widget asWidget() {
        return viewPanel;
    }

    @Override
    public void dispose() {
        resourceModelPresenter = DisposeUtil.safelyDispose(
                resourceModelPresenter, errorHandler);
        selectionModelPresenter = DisposeUtil.safelyDispose(
                selectionModelPresenter, errorHandler);
        visualizationModel = DisposeUtil.safelyDispose(visualizationModel,
                errorHandler);
    }

    @ForTest
    protected void doRestore(Memento state,
            PersistableRestorationService restorationService,
            ResourceSetAccessor accessor) {

        assert isInitialized : "view has to be initialized before restoring it";

        contentDisplay.startRestore();

        // restoreGrouping(state.getChild(MEMENTO_GROUPING));
        restoreGrouping(state.getChild(MEMENTO_GROUPING));
        restore(resourceModel, state, MEMENTO_RESOURCE_MODEL,
                restorationService, accessor);
        restore(selectionModel, state, MEMENTO_SELECTION_MODEL,
                restorationService, accessor);
        contentDisplay.restore(state.getChild(MEMENTO_CONTENT_DISPLAY),
                restorationService, accessor);

        managedSlotMappingConfigurationPersistence.restore(
                managedSlotMappingConfiguration,
                state.getChild(MEMENTO_SLOT_MAPPINGS));

        setLabel((String) state.getValue(MEMENTO_LABEL_KEY));

        contentDisplay.endRestore();
    }

    @Override
    public String getContentType() {
        return contentType;
    }

    @Override
    public String getLabel() {
        return label;
    }

    @Override
    public VisualizationModel getModel() {
        assert visualizationModel != null : "view has been disposed";
        return visualizationModel;
    }

    protected String getModuleBase() {
        return GWT.getModuleBaseURL();
    }

    @Override
    public ResourceModel getResourceModel() {
        return resourceModel;
    }

    @Override
    public SelectionModel getSelectionModel() {
        return selectionModel;
    }

    @Override
    public void init() {
        assert !isInitialized : "view has already been initialized";

        resourceModelPresenter.init();
        initUI();

        isInitialized = true;
    }

    private void initConfigurationPanelUI() {
        configurationBar = new DockPanel();
        configurationBar.setSize("100%", "");
        configurationBar.setStyleName(CSS_VIEW_CONFIGURATION_PANEL);

        initResourceModelPresenter();
        initSideBarExpander();
        initSelectionModelPresenter();
    }

    private void initResourceModelPresenter() {
        Widget widget = resourceModelPresenter.asWidget();

        configurationBar.add(widget, DockPanel.WEST);
        configurationBar.setCellHorizontalAlignment(widget,
                HasAlignment.ALIGN_LEFT);
    }

    private void initSelectionModelPresenter() {
        selectionModelPresenter.init();

        Widget widget = selectionModelPresenter.asWidget();
        configurationBar.add(widget, DockPanel.EAST);
        configurationBar.setCellHorizontalAlignment(widget,
                HasAlignment.ALIGN_RIGHT);
        configurationBar.setCellWidth(widget, "100%"); // eats up all space
    }

    private void initSideBar() {
        assert sideBar == null;
        assert sidePanelSections != null;

        sideBar = new StackPanel();
        sideBar.setStyleName(CSS_CONFIGURATION_PANEL);
        sideBar.setVisible(false);

        for (SidePanelSection sidePanelSection : sidePanelSections) {
            sideBar.add(sidePanelSection.getWidget(),
                    sidePanelSection.getSectionTitle());
        }
    }

    private void initSideBarExpander() {
        ImageButton expander = ImageButton.createExpanderButton();

        expander.setStyleName(CSS_EXPANDER);

        expander.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                sideBar.setVisible(!sideBar.isVisible());
                updateContentDisplaySize();
            }
        });

        configurationBar.add(expander, DockPanel.EAST);
        configurationBar.setCellHorizontalAlignment(expander,
                HasAlignment.ALIGN_RIGHT);
    }

    protected void initUI() {
        initConfigurationPanelUI();
        initSideBar();

        viewPanel = new ViewPanel();

        viewPanel.setBorderWidth(0);
        viewPanel.setSpacing(0);

        viewPanel.setSize("500px", "300px");

        viewPanel.add(configurationBar, DockPanel.NORTH);
        viewPanel.add(contentDisplay.asWidget(), DockPanel.CENTER);
        viewPanel.add(sideBar, DockPanel.EAST);

        viewPanel.setCellHeight(contentDisplay.asWidget(), "100%");
    }

    @Override
    public boolean isAdaptableTo(Class<?> clazz) {
        return contentDisplay.isAdaptableTo(clazz);
    }

    // XXX remove once content display lifecycle working
    public boolean isReady() {
        return contentDisplay.isReady();
    }

    @Override
    public void restore(final Memento state,
            final PersistableRestorationService restorationService,
            final ResourceSetAccessor accessor) {

        /*
         * wait for content to be ready (needed for graph view swf loading on
         * restore)
         */
        // XXX this might be the cause for issue 25
        // TODO introduce proper view content display lifecycle instead
        if (contentDisplay.isReady()) {
            doRestore(state, restorationService, accessor);
        } else {
            new Timer() {
                @Override
                public void run() {
                    restore(state, restorationService, accessor);
                }
            }.schedule(200);
        }
    }

    private void restore(Object target, Memento parentMemento,
            String targetMementoKey,
            PersistableRestorationService restorationService,
            ResourceSetAccessor accessor) {

        if (target instanceof Persistable) {
            ((Persistable) target).restore(
                    parentMemento.getChild(targetMementoKey),
                    restorationService, accessor);
        }
    }

    // TODO extract constants
    private void restoreGrouping(Memento groupingMemento) {
        assert groupingMemento != null;

        String categorizerType = (String) groupingMemento.getValue("type");

        if ("byProperty".equals(categorizerType)) {
            String property = (String) groupingMemento.getValue("property");
            visualizationModel
                    .setCategorizer(new ResourceByPropertyMultiCategorizer(
                            property));
        } else if ("byUri".equals(categorizerType)) {
            visualizationModel
                    .setCategorizer(new ResourceByUriMultiCategorizer());
        }
    }

    private void save(Object target, Memento parentMemento,
            String targetMementoKey, ResourceSetCollector resourceSetCollector) {

        if (target instanceof Persistable) {
            parentMemento.addChild(targetMementoKey,
                    ((Persistable) target).save(resourceSetCollector));
        }
    }

    @Override
    public Memento save(ResourceSetCollector resourceSetCollector) {
        Memento memento = new Memento();

        saveGrouping(memento);
        save(selectionModel, memento, MEMENTO_SELECTION_MODEL,
                resourceSetCollector);
        save(resourceModel, memento, MEMENTO_RESOURCE_MODEL,
                resourceSetCollector);
        memento.addChild(MEMENTO_CONTENT_DISPLAY,
                contentDisplay.save(resourceSetCollector));

        memento.addChild(MEMENTO_SLOT_MAPPINGS,
                managedSlotMappingConfigurationPersistence
                        .save(managedSlotMappingConfiguration));

        memento.setValue(MEMENTO_LABEL_KEY, getLabel());

        return memento;
    }

    // TODO extract constants
    private void saveGrouping(Memento memento) {
        Memento groupingMemento = new Memento();

        ResourceMultiCategorizer categorizer = visualizationModel
                .getCategorizer();
        if (categorizer instanceof ResourceByPropertyMultiCategorizer) {
            groupingMemento.setValue("type", "byProperty");
            groupingMemento.setValue("property",
                    ((ResourceByPropertyMultiCategorizer) categorizer)
                            .getProperty());
        } else if (categorizer instanceof ResourceByUriMultiCategorizer) {
            groupingMemento.setValue("type", "byUri");
        }

        memento.addChild(MEMENTO_GROUPING, groupingMemento);
    }

    @Override
    public void setLabel(String label) {
        this.label = label;
    }

    /**
     * Sets the size of the default view, not including decorations such as
     * border, margin, and padding (and thus different from offset width and
     * height).
     *
     * @param width
     *            width in pixels
     * @param height
     *            height in pixels
     */
    private void setSize(int width, int height) {
        assert height >= 0;
        assert width >= 0;

        this.width = width;
        this.height = height;

        updateContentDisplaySize();
    }

    private void updateContentDisplaySize() {
        /*
         * special resize method required, because otherwise window height
         * cannot be reduced by dragging - see
         * http://code.google.com/p/google-web-toolkit/issues/detail?id=316
         */

        int targetHeight = height - configurationBar.getOffsetHeight();
        int targetWidth = sideBar.isVisible() ? width
                - sideBar.getOffsetWidth() : width;

        contentDisplay.setSize(targetWidth, targetHeight);
    }

}
TOP

Related Classes of org.thechiselgroup.choosel.core.client.visualization.DefaultView$ViewPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.