Package pivot.wtk.skin.terra

Source Code of pivot.wtk.skin.terra.TerraFormSkin

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you 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 pivot.wtk.skin.terra;

import pivot.collections.ArrayList;
import pivot.collections.Sequence;

import pivot.wtk.Component;
import pivot.wtk.Dimensions;
import pivot.wtk.Form;
import pivot.wtk.FormAttributeListener;
import pivot.wtk.FormListener;
import pivot.wtk.HorizontalAlignment;
import pivot.wtk.ImageView;
import pivot.wtk.Label;
import pivot.wtk.MessageType;
import pivot.wtk.Separator;
import pivot.wtk.Theme;
import pivot.wtk.media.Image;
import pivot.wtk.skin.ContainerSkin;

/**
* Form skin.
*
* @author gbrown
*/
public class TerraFormSkin extends ContainerSkin
    implements FormListener, FormAttributeListener {
    private ArrayList<Separator> separators = new ArrayList<Separator>();
    private ArrayList<ArrayList<Label>> labels = new ArrayList<ArrayList<Label>>();
    private ArrayList<ArrayList<ImageView>> flagImageViews = new ArrayList<ArrayList<ImageView>>();

    private boolean rightAlignLabels = true;
    private HorizontalAlignment fieldAlignment = HorizontalAlignment.LEFT;
    private int horizontalSpacing = 6;
    private int verticalSpacing = 6;
    private int flagImageOffset = 4;
    private boolean showFirstSectionHeading = false;

    private static final int FLAG_IMAGE_SIZE = 16;

    @Override
    public void install(Component component) {
        super.install(component);

        Form form = (Form)component;
        form.getFormListeners().add(this);
        form.getFormAttributeListeners().add(this);

        Form.SectionSequence sections = form.getSections();
        for (int i = 0, n = sections.getLength(); i < n; i++) {
            insertSection(sections.get(i), i);
        }
    }

    @Override
    public void uninstall() {
        Form form = (Form)getComponent();
        form.getFormListeners().remove(this);
        form.getFormAttributeListeners().remove(this);

        removeSections(0, form.getSections());

        super.uninstall();
    }

    public int getPreferredWidth(int height) {
        int preferredWidth = 0;

        // Preferred width is maximum of either the sum of the maximum label
        // width, maximum field width, horizontal spacing, flag image offset,
        // and flag image size values or the maximum separator width
        int maximumLabelWidth = 0;
        int maximumFieldWidth = 0;
        int maximumSeparatorWidth = 0;

        Form form = (Form)getComponent();
        Form.SectionSequence sections = form.getSections();

        for (int sectionIndex = 0, sectionCount = sections.getLength();
            sectionIndex < sectionCount; sectionIndex++) {
            Form.Section section = sections.get(sectionIndex);

            if (showFirstSectionHeading
                || sectionIndex > 0) {
                Separator separator = separators.get(sectionIndex);
                maximumSeparatorWidth = Math.max(maximumSeparatorWidth,
                    separator.getPreferredWidth());
            }

            for (int fieldIndex = 0, fieldCount = section.getLength();
                fieldIndex < fieldCount; fieldIndex++) {
                Component field = section.get(fieldIndex);

                if (field.isDisplayable()) {
                    Label label = labels.get(sectionIndex).get(fieldIndex);
                    maximumLabelWidth = Math.max(maximumLabelWidth,
                        label.getPreferredWidth(-1));
                    maximumFieldWidth = Math.max(maximumFieldWidth,
                        field.getPreferredWidth(-1));
                }
            }
        }

        preferredWidth = Math.max(maximumLabelWidth + horizontalSpacing + maximumFieldWidth
            + flagImageOffset + FLAG_IMAGE_SIZE, maximumSeparatorWidth);

        return preferredWidth;
    }

    public int getPreferredHeight(int width) {
        int preferredHeight = 0;

        Form form = (Form)getComponent();
        Form.SectionSequence sections = form.getSections();

        // If justified and constrained, determine field width constraint
        int fieldWidth = -1;

        if (fieldAlignment == HorizontalAlignment.JUSTIFY
            && width != -1) {
            int maximumLabelWidth = 0;

            for (int sectionIndex = 0, sectionCount = sections.getLength();
                sectionIndex < sectionCount; sectionIndex++) {
                Form.Section section = sections.get(sectionIndex);

                for (int fieldIndex = 0, fieldCount = section.getLength();
                    fieldIndex < fieldCount; fieldIndex++) {
                    Component field = section.get(fieldIndex);

                    if (field.isDisplayable()) {
                        Label label = labels.get(sectionIndex).get(fieldIndex);
                        maximumLabelWidth = Math.max(maximumLabelWidth,
                            label.getPreferredWidth(-1));
                    }
                }
            }

            fieldWidth = Math.max(0, width - (maximumLabelWidth
                + horizontalSpacing + flagImageOffset + FLAG_IMAGE_SIZE));
        }

        // Preferred height is the sum of the maximum value of the label,
        // field, and flag image for each row, plus vertical spacing and
        // preferred separator heights
        for (int sectionIndex = 0, sectionCount = sections.getLength();
            sectionIndex < sectionCount; sectionIndex++) {
            Form.Section section = sections.get(sectionIndex);

            if (showFirstSectionHeading
                || sectionIndex > 0) {
                Separator separator = separators.get(sectionIndex);
                preferredHeight += separator.getPreferredHeight(width);
                preferredHeight += verticalSpacing;
            }

            for (int fieldIndex = 0, fieldCount = section.getLength();
                fieldIndex < fieldCount; fieldIndex++) {
                Component field = section.get(fieldIndex);

                if (field.isDisplayable()) {
                    Label label = labels.get(sectionIndex).get(fieldIndex);

                    int preferredRowHeight = Math.max(label.getPreferredHeight(-1),
                        Math.max(field.getPreferredHeight(fieldWidth), FLAG_IMAGE_SIZE));
                    preferredHeight += preferredRowHeight;

                    if (fieldIndex > 0) {
                        preferredHeight += verticalSpacing;
                    }
                }
            }
        }

        return preferredHeight;
    }

    public Dimensions getPreferredSize() {
        // TODO Optimize
        return new Dimensions(getPreferredWidth(-1), getPreferredHeight(-1));
    }

    public void layout() {
        Form form = (Form)getComponent();
        Form.SectionSequence sections = form.getSections();

        // Determine the maximum label and field widths
        int maximumLabelWidth = 0;
        int maximumFieldWidth = 0;

        for (int sectionIndex = 0, sectionCount = sections.getLength();
            sectionIndex < sectionCount; sectionIndex++) {
            Form.Section section = sections.get(sectionIndex);

            for (int fieldIndex = 0, fieldCount = section.getLength();
                fieldIndex < fieldCount; fieldIndex++) {
                Component field = section.get(fieldIndex);

                if (field.isDisplayable()) {
                    Label label = labels.get(sectionIndex).get(fieldIndex);
                    maximumLabelWidth = Math.max(maximumLabelWidth,
                        label.getPreferredWidth(-1));
                    maximumFieldWidth = Math.max(maximumFieldWidth,
                        field.getPreferredWidth(-1));
                }
            }
        }

        // Determine the maximum field width
        int width = getWidth();
        int availableFieldWidth = Math.max(0, width - (maximumLabelWidth
            + horizontalSpacing + flagImageOffset + FLAG_IMAGE_SIZE));

        // Lay out the components
        int rowY = 0;

        for (int sectionIndex = 0, sectionCount = sections.getLength();
            sectionIndex < sectionCount; sectionIndex++) {
            Form.Section section = sections.get(sectionIndex);

            Separator separator = separators.get(sectionIndex);
            if (sectionIndex == 0
                && !showFirstSectionHeading) {
                separator.setVisible(false);
            } else {
                separator.setVisible(true);
                separator.setSize(width, separator.getPreferredHeight(width));
                separator.setLocation(0, rowY);
                rowY += separator.getHeight();
            }

            for (int fieldIndex = 0, fieldCount = section.getLength();
                fieldIndex < fieldCount; fieldIndex++) {
                Component field = section.get(fieldIndex);

                Label label = labels.get(sectionIndex).get(fieldIndex);
                ImageView flagImageView = flagImageViews.get(sectionIndex).get(fieldIndex);

                if (field.isDisplayable()) {
                    // Show the row components
                    label.setVisible(true);
                    field.setVisible(true);
                    flagImageView.setVisible(true);

                    // Set the row component sizes
                    label.setSize(label.getPreferredSize());

                    Dimensions fieldSize = null;
                    if (fieldAlignment == HorizontalAlignment.JUSTIFY) {
                        fieldSize = new Dimensions(availableFieldWidth,
                            field.getPreferredHeight(availableFieldWidth));
                    } else {
                        fieldSize = field.getPreferredSize();
                    }

                    field.setSize(fieldSize);
                    flagImageView.setSize(flagImageView.getPreferredSize());

                    int rowHeight = Math.max(label.getHeight(),
                        Math.max(field.getHeight(), FLAG_IMAGE_SIZE));

                    // Set the row component locations
                    int labelX = rightAlignLabels ? maximumLabelWidth - label.getWidth() : 0;
                    label.setLocation(labelX, rowY);

                    int fieldX = 0;
                    switch(fieldAlignment) {
                        case LEFT:
                        case JUSTIFY: {
                            fieldX = maximumLabelWidth + horizontalSpacing;
                            break;
                        }

                        case RIGHT: {
                            fieldX = maximumLabelWidth + horizontalSpacing
                                + Math.max(0, Math.max(availableFieldWidth, maximumFieldWidth)
                                    - field.getWidth());
                            break;
                        }

                        case CENTER: {
                            fieldX = maximumLabelWidth + horizontalSpacing
                                + Math.max(0, (Math.max(availableFieldWidth, maximumFieldWidth)
                                    - field.getWidth()) / 2);
                            break;
                        }
                    }

                    field.setLocation(fieldX, rowY);
                    flagImageView.setLocation(fieldX + field.getWidth() + flagImageOffset,
                        rowY + (rowHeight - flagImageView.getHeight()) / 2);

                    // Update the row y-coordinate
                    rowY += rowHeight + verticalSpacing;
                } else {
                    // Hide the row components
                    label.setVisible(false);
                    field.setVisible(false);
                    flagImageView.setVisible(false);
                }
            }
        }
    }

    public boolean getRightAlignLabels() {
        return rightAlignLabels;
    }

    public void setRightAlignLabels(boolean rightAlignLabels) {
        this.rightAlignLabels = rightAlignLabels;
    }

    public HorizontalAlignment getFieldAlignment() {
        return fieldAlignment;
    }

    public void setFieldAlignment(HorizontalAlignment fieldAlignment) {
        this.fieldAlignment = fieldAlignment;
        repaintComponent();
    }

    public final void setFieldAlignment(String fieldAlignment) {
        if (fieldAlignment == null) {
            throw new IllegalArgumentException("fieldAlignment is null.");
        }

        setFieldAlignment(HorizontalAlignment.decode(fieldAlignment));
    }

    public int getHorizontalSpacing() {
        return horizontalSpacing;
    }

    public void setHorizontalSpacing(int horizontalSpacing) {
        this.horizontalSpacing = horizontalSpacing;
        invalidateComponent();
    }

    public final void setHorizontalSpacing(Number horizontalSpacing) {
        if (horizontalSpacing == null) {
            throw new IllegalArgumentException("horizontalSpacing is null.");
        }

        setHorizontalSpacing(horizontalSpacing.intValue());
    }

    public int getVerticalSpacing() {
        return verticalSpacing;
    }

    public void setVerticalSpacing(int verticalSpacing) {
        this.verticalSpacing = verticalSpacing;
        invalidateComponent();
    }

    public final void setVerticalSpacing(Number verticalSpacing) {
        if (verticalSpacing == null) {
            throw new IllegalArgumentException("verticalSpacing is null.");
        }

        setVerticalSpacing(verticalSpacing.intValue());
    }

    public int getFlagImageOffset() {
        return flagImageOffset;
    }

    public void setFlagImageOffset(int flagImageOffset) {
        this.flagImageOffset = flagImageOffset;
        invalidateComponent();
    }

    public final void setFlagImageOffset(Number flagImageOffset) {
        if (flagImageOffset == null) {
            throw new IllegalArgumentException("flagImageOffset is null.");
        }

        setFlagImageOffset(flagImageOffset.intValue());
    }

    public boolean isShowFirstSectionHeading() {
        return showFirstSectionHeading;
    }

    public void setShowFirstSectionHeading(boolean showFirstSectionHeading) {
        this.showFirstSectionHeading = showFirstSectionHeading;
        invalidateComponent();
    }

    // Form events
    public void sectionInserted(Form form, int index) {
        insertSection(form.getSections().get(index), index);
    }

    public void sectionsRemoved(Form form, int index, Sequence<Form.Section> removed) {
        removeSections(index, removed);
    }

    public void sectionHeadingChanged(Form.Section section) {
        updateSectionHeading(section);
    }

    public void fieldInserted(Form.Section section, int index) {
        insertField(section, section.get(index), index);
    }

    public void fieldsRemoved(Form.Section section, int index, Sequence<Component> fields) {
        removeFields(section, index, fields.getLength());
    }

    // Form attribute events
    public void nameChanged(Form form, Component field, String previousName) {
        Form.Section section = Form.getSection(field);
        updateFieldName(section, section.indexOf(field));
    }

    public void flagChanged(Form form, Component field, Form.Flag previousFlag) {
        Form.Section section = Form.getSection(field);
        updateFieldFlag(section, section.indexOf(field));
    }

    // Implementation methods
    private void insertSection(Form.Section section, int index) {
        Form form = (Form)getComponent();

        // Insert separator
        Separator separator = new Separator(section.getHeading());
        separators.insert(separator, index);
        form.add(separator);

        // Insert field label and flag image view lists
        ArrayList<Label> sectionLabels = new ArrayList<Label>();
        labels.insert(sectionLabels, index);

        ArrayList<ImageView> sectionFlagImageViews = new ArrayList<ImageView>();
        flagImageViews.insert(sectionFlagImageViews, index);

        // Insert fields
        for (int i = 0, n = section.getLength(); i < n; i++) {
            insertField(section, section.get(i), i);
        }

        invalidateComponent();
    }

    private void removeSections(int index, Sequence<Form.Section> removed) {
        Form form = (Form)getComponent();

        for (int i = 0, n = removed.getLength(); i < n; i++) {
            // Remove fields
            Form.Section section = removed.get(i);
            for (int j = 0; j < n; j++) {
                removeFields(section, 0, section.getLength());
            }

            // Remove field label and flag image view lists
            labels.remove(index, n);
            flagImageViews.remove(index, n);

            // Remove separators
            Sequence<Separator> removedSeparators = separators.remove(index, n);
            for (int j = 0; j < n; j++) {
                form.remove(removedSeparators.get(j));
            }
        }

        invalidateComponent();
    }

    private void insertField(Form.Section section, Component field, int index) {
        Form form = (Form)getComponent();
        int sectionIndex = form.getSections().indexOf(section);

        // Create the label
        Label label = new Label();
        labels.get(sectionIndex).insert(label, index);
        form.add(label);
        updateFieldName(section, index);

        // Create the flag image view
        ImageView flagImageView = new ImageView();
        flagImageViews.get(sectionIndex).insert(flagImageView, index);
        form.add(flagImageView);
        updateFieldFlag(section, index);

        invalidateComponent();
    }

    private void removeFields(Form.Section section, int index, int count) {
        Form form = (Form)getComponent();
        int sectionIndex = form.getSections().indexOf(section);

        // Remove the labels
        Sequence<Label> removedLabels = labels.get(sectionIndex).remove(index, count);
        for (int i = 0; i < count; i++) {
            form.remove(removedLabels.get(i));
        }

        // Remove the flag image views
        Sequence<ImageView> removedFlagImageViews = flagImageViews.get(sectionIndex).remove(index, count);
        for (int i = 0; i < count; i++) {
            form.remove(removedFlagImageViews.get(i));
        }

        invalidateComponent();
    }

    private void updateSectionHeading(Form.Section section) {
        Form form = (Form)getComponent();
        int sectionIndex = form.getSections().indexOf(section);

        Separator separator = separators.get(sectionIndex);
        separator.setHeading(section.getHeading());
    }

    private void updateFieldName(Form.Section section, int fieldIndex) {
        Form form = (Form)getComponent();
        Component field = section.get(fieldIndex);

        int sectionIndex = form.getSections().indexOf(section);
        Label label = labels.get(sectionIndex).get(fieldIndex);
        String name = Form.getName(field);
        label.setText((name == null) ? "" : name + ":");
    }

    private void updateFieldFlag(Form.Section section, int fieldIndex) {
        Form form = (Form)getComponent();
        Component field = section.get(fieldIndex);

        int sectionIndex = form.getSections().indexOf(section);
        ImageView flagImageView = flagImageViews.get(sectionIndex).get(fieldIndex);
        Form.Flag flag = Form.getFlag(field);

        Image flagImage = null;
        String flagMessage = null;

        if (flag != null) {
            TerraTheme theme = (TerraTheme)Theme.getTheme();
            MessageType flagMessageType = flag.getMessageType();
            flagImage = theme.getSmallMessageIcon(flagMessageType);
            flagMessage = flag.getMessage();
        }

        flagImageView.setImage(flagImage);
        flagImageView.setTooltipText(flagMessage);
    }
}
TOP

Related Classes of pivot.wtk.skin.terra.TerraFormSkin

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.