Package org.thechiselgroup.choosel.visualization_component.text.client

Source Code of org.thechiselgroup.choosel.visualization_component.text.client.TextVisualization

/*******************************************************************************
* 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.visualization_component.text.client;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.thechiselgroup.choosel.core.client.ui.SidePanelSection;
import org.thechiselgroup.choosel.core.client.util.DataType;
import org.thechiselgroup.choosel.core.client.util.collections.CollectionUtils;
import org.thechiselgroup.choosel.core.client.util.collections.Delta;
import org.thechiselgroup.choosel.core.client.util.collections.LightweightCollection;
import org.thechiselgroup.choosel.core.client.util.math.MathUtils;
import org.thechiselgroup.choosel.core.client.util.math.NumberArray;
import org.thechiselgroup.choosel.core.client.visualization.model.AbstractViewContentDisplay;
import org.thechiselgroup.choosel.core.client.visualization.model.Slot;
import org.thechiselgroup.choosel.core.client.visualization.model.VisualItem;

import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Widget;

// XXX memento not implemented
// XXX order does not update when description property changes
public class TextVisualization extends AbstractViewContentDisplay {

    // TODO move back into factory
    public final static String ID = "org.thechiselgroup.choosel.visualization_component.Text";

    public final static Slot LABEL_SLOT = new Slot("label", "Label",
            DataType.TEXT);

    public static final Slot FONT_SIZE_SLOT = new Slot("font-size",
            "Font Size", DataType.NUMBER);

    private static final String CSS_TAG_CLOUD = "choosel-TextViewContentDisplay-TagCloud";

    private List<TextItem> items = new ArrayList<TextItem>();

    public static final String CSS_LIST_VIEW_SCROLLBAR = "listViewScrollbar";

    private final TextItemContainer textItemContainer;

    private DoubleToGroupValueMapper<String> groupValueMapper;

    private boolean tagCloud = true;

    private Comparator<TextItem> comparator = new Comparator<TextItem>() {
        @Override
        public int compare(TextItem o1, TextItem o2) {
            return o1.getLabel().getText()
                    .compareToIgnoreCase(o2.getLabel().getText());
        }
    };

    public TextVisualization() {
        this(new DefaultTextItemContainer());
    }

    // for test: can change container
    protected TextVisualization(TextItemContainer textItemContainer) {
        assert textItemContainer != null;

        this.textItemContainer = textItemContainer;

        initGroupValueMapper();
    }

    /**
     * <p>
     * Creates TextItems for the added resource items and adds them to the user
     * interface.
     * </p>
     * <p>
     * <b>PERFORMANCE NOTE</b>: This method is designed such that the items are
     * only sorted once, and then there is just a single pass along the sorted
     * items.
     * </p>
     */
    private void addVisualItems(LightweightCollection<VisualItem> addedVisualItems) {

        assert addedVisualItems != null;

        // PERFORMANCE: do not execute sort if nothing changes
        if (addedVisualItems.isEmpty()) {
            return;
        }

        for (VisualItem visualItem : addedVisualItems) {
            TextItem textItem = createTextItem(visualItem);
            items.add(textItem);
        }

        // Time complexity: O(n*log(n)).
        Collections.sort(items, comparator);

        /*
         * Time complexity: O(n). Iterate over items and check for addedToPanel
         * flag to prevent IndexOutOfBoundsExceptions and keep execution time
         * linear to number of ResourceItems in this view.
         */
        for (int i = 0; i < items.size(); i++) {
            TextItem textItem = items.get(i);
            if (!textItem.isAddedToPanel()) {
                textItemContainer.insert(textItem.getLabel(), i);
                textItem.updateContent();
                textItem.updateStatusStyling();
                textItem.setAddedToPanel(true);
            }
        }
    }

    private void applyTagCloudCSS(boolean tagCloud) {
        if (tagCloud) {
            textItemContainer.addStyleName(CSS_TAG_CLOUD);
        } else {
            textItemContainer.removeStyleName(CSS_TAG_CLOUD);
        }
    }

    private TextItem createTextItem(VisualItem visualItem) {
        TextItem textItem = new TextItem(visualItem);

        TextItemLabel label = textItemContainer.createTextItemLabel(textItem
                .getResourceItem());

        textItem.init(label);

        visualItem.setDisplayObject(textItem);

        return textItem;
    }

    @Override
    public Widget createWidget() {
        Widget widget = textItemContainer.createWidget();
        applyTagCloudCSS(tagCloud);
        return widget;
    }

    @Override
    public String getName() {
        return "Text";
    }

    @Override
    public SidePanelSection[] getSidePanelSections() {
        FlowPanel settingsPanel = new FlowPanel();

        final CheckBox oneItemPerRowBox = new CheckBox("One item per row");
        oneItemPerRowBox
                .addValueChangeHandler(new ValueChangeHandler<Boolean>() {

                    @Override
                    public void onValueChange(ValueChangeEvent<Boolean> event) {
                        setTagCloud(!oneItemPerRowBox.getValue());
                    }

                });
        settingsPanel.add(oneItemPerRowBox);
        oneItemPerRowBox.setValue(!tagCloud);

        return new SidePanelSection[] { new SidePanelSection("Settings",
                settingsPanel), };
    }

    @Override
    public Slot[] getSlots() {
        return new Slot[] { LABEL_SLOT, FONT_SIZE_SLOT };
    }

    private void initGroupValueMapper() {
        groupValueMapper = new DoubleToGroupValueMapper<String>(
                new EquidistantBinBoundaryCalculator(), CollectionUtils.toList(
                        "10px", "14px", "18px", "22px", "26px"));
    }

    private void removeTextItem(TextItem textItem) {
        /*
         * whole row needs to be removed, otherwise lots of empty rows consume
         * the whitespace
         */
        TextItemLabel label = textItem.getLabel();
        items.remove(textItem);
        textItemContainer.remove(label);
    }

    public void setTagCloud(boolean tagCloud) {
        if (tagCloud == this.tagCloud) {
            return;
        }

        this.tagCloud = tagCloud;

        applyTagCloudCSS(tagCloud);
    }

    @Override
    public void update(Delta<VisualItem> delta,
            LightweightCollection<Slot> updatedSlots) {

        addVisualItems(delta.getAddedElements());

        for (VisualItem visualItem : delta.getUpdatedElements()) {
            TextItem textItem = visualItem.<TextItem> getDisplayObject();
            textItem.updateContent();
            textItem.updateStatusStyling();
        }

        for (VisualItem visualItem : delta.getRemovedElements()) {
            removeTextItem(visualItem.<TextItem> getDisplayObject());
        }

        if (!updatedSlots.isEmpty()) {
            for (VisualItem visualItem : getVisualItems()) {
                visualItem.<TextItem> getDisplayObject().updateContent();
            }

        }

        if (!items.isEmpty()) {
            updateFontSizes();
        }
    }

    private void updateFontSizes() {
        assert !items.isEmpty();

        NumberArray fontSizeValues = MathUtils.createNumberArray();

        boolean onlyOneValue = true;
        boolean first = true;
        double firstValue = 0;
        for (TextItem textItem : items) {
            double itemValue = textItem.getFontSizeValue();

            if (first) {
                first = false;
                firstValue = itemValue;
            } else if (firstValue != itemValue) {
                onlyOneValue = false;
            }

            fontSizeValues.push(itemValue);
        }

        if (!onlyOneValue) {
            groupValueMapper.setNumberValues(fontSizeValues);
            for (TextItem textItem : items) {
                textItem.scaleFont(groupValueMapper);
            }
        } else {
            for (TextItem textItem : items) {
                textItem.setFontSize("12px");
            }
        }
    }
}
TOP

Related Classes of org.thechiselgroup.choosel.visualization_component.text.client.TextVisualization

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.