org.kaaproject.avro.ui.gwt.client.widget.FieldWidgetPanel.java Source code

Java tutorial

Introduction

Here is the source code for org.kaaproject.avro.ui.gwt.client.widget.FieldWidgetPanel.java

Source

/*
 * Copyright 2014-2015 CyberVision, Inc.
 *
 * 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.kaaproject.avro.ui.gwt.client.widget;

import org.kaaproject.avro.ui.gwt.client.AvroUiResources;
import org.kaaproject.avro.ui.gwt.client.AvroUiResources.AvroUiStyle;
import org.kaaproject.avro.ui.gwt.client.util.Utils;
import org.kaaproject.avro.ui.shared.FormField;
import org.kaaproject.avro.ui.shared.FormField.ChangeListener;

import com.google.gwt.animation.client.Animation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;

public class FieldWidgetPanel extends Composite implements HasValue<Boolean>, ClickHandler, ChangeListener {

    interface FieldWidgetPanelUiBinder extends UiBinder<Widget, FieldWidgetPanel> {
    }

    private static FieldWidgetPanelUiBinder uiBinder = GWT.create(FieldWidgetPanelUiBinder.class);

    private static final int OPEN_ANIMATION_DURATION = 350;

    private static ContentAnimation contentAnimation;

    @UiField
    public FlowPanel fieldSet;
    @UiField
    public Label legendLabel;
    @UiField
    public Label legendNotesLabel;
    @UiField
    public Image arrowImage;
    @UiField
    public CheckBox legendBox;
    @UiField
    public SimplePanel legendPanel;
    @UiField
    public SimplePanel contentPanel;

    @UiField(provided = true)
    public final AvroUiResources avroUiResources;
    @UiField(provided = true)
    public final AvroUiStyle avroUiStyle;

    /** Signals whether the fieldset is opened. */
    private boolean isOpen;

    private FormField field;

    public FieldWidgetPanel(AvroUiStyle style, FormField field, boolean readOnly, boolean openByDefault) {

        this.field = field;

        avroUiResources = Utils.resources;
        avroUiStyle = style;

        initWidget(uiBinder.createAndBindUi(this));

        contentPanel.getElement().getStyle().setProperty("padding", "0px");
        contentPanel.getElement().getStyle().setDisplay(Display.INLINE_BLOCK);

        legendLabel.setText(field.getDisplayName());
        if (!field.isOptional()) {
            legendLabel.addStyleName(avroUiStyle.requiredField());
        }

        if (field.isOverride()) {
            arrowImage.setVisible(false);
            legendBox.setVisible(true);
            legendBox.setEnabled(!readOnly && !field.isReadOnly());
            if (!readOnly && !field.isReadOnly()) {
                legendBox.addClickHandler(this);
                field.addChangeListener(this);
            }
            setOpen(field.isChanged(), false);
        } else {
            legendBox.setVisible(false);
            arrowImage.setVisible(true);
            arrowImage.addClickHandler(this);
            setOpen(openByDefault, false);
        }
        setContentDisplay(false);
    }

    @Override
    public void onChanged(boolean changed) {
        setValue(changed, false, true);
    }

    public void setContent(Widget widget) {
        contentPanel.setWidget(widget);
        setContentDisplay(false);
    }

    public Widget getContent() {
        return contentPanel.getWidget();
    }

    public void setLegendWidget(Widget widget) {
        legendPanel.setVisible(true);
        legendPanel.setWidget(widget);
    }

    public void setLegendNotes(String notes) {
        legendNotesLabel.setVisible(true);
        legendNotesLabel.setText(notes);
    }

    @Override
    public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Boolean> handler) {
        return addHandler(handler, ValueChangeEvent.getType());
    }

    @Override
    public Boolean getValue() {
        return isOpen;
    }

    @Override
    public void setValue(Boolean value) {
        setValue(value, false);
    }

    @Override
    public void setValue(Boolean value, boolean fireEvents) {
        setValue(value, fireEvents, false);
    }

    public void setValue(final Boolean value, final boolean fireEvents, boolean animate) {
        if (value == this.isOpen) {
            return;
        }
        Boolean before = this.isOpen;
        field.setChanged(value, fireEvents);
        setOpen(value, animate);
        if (fireEvents) {
            ValueChangeEvent.fireIfNotEqual(this, before, value);
        }
    }

    public boolean isOpen() {
        return isOpen;
    }

    public void setOpen(boolean isOpen, boolean animate) {
        if (this.isOpen != isOpen) {
            this.isOpen = isOpen;
            if (field.isOverride()) {
                legendBox.setValue(isOpen);
            }
            setContentDisplay(animate);
        }
    }

    @Override
    public void onClick(ClickEvent event) {
        setValue(!isOpen, true, true);
    }

    private void setContentDisplay(boolean animate) {
        if (contentAnimation == null) {
            contentAnimation = new ContentAnimation();
        }
        contentAnimation.setOpen(this, animate);
    }

    private void updateStyles() {
        if (isOpen) {
            fieldSet.removeStyleName(avroUiStyle.fieldsetInvisible());
            fieldSet.addStyleName(avroUiStyle.fieldsetVisible());
            arrowImage.setResource(avroUiResources.arrowBottomImage());
        } else {
            fieldSet.removeStyleName(avroUiStyle.fieldsetVisible());
            fieldSet.addStyleName(avroUiStyle.fieldsetInvisible());
            arrowImage.setResource(avroUiResources.arrowRightImage());
        }

    }

    /**
     * An {@link Animation} used to open the content.
     */
    private static class ContentAnimation extends Animation {
        /**
         * Whether the item is being opened or closed.
         */
        private boolean opening;

        /**
         * The {@link DisclosurePanel} being affected.
         */
        private FieldWidgetPanel curPanel;

        /**
         * Open or close the content.
         * 
         * @param panel the panel to open or close
         * @param animate true to animate, false to open instantly
         */
        public void setOpen(FieldWidgetPanel panel, boolean animate) {
            // Immediately complete previous open
            cancel();

            // Open the new item
            if (animate) {
                curPanel = panel;
                opening = panel.isOpen;
                run(OPEN_ANIMATION_DURATION);
            } else {
                panel.updateStyles();
                panel.contentPanel.setVisible(panel.isOpen);
                panel.contentPanel.getElement().getStyle().setDisplay(Display.INLINE_BLOCK);
                if (panel.isOpen) {
                    panel.contentPanel.getElement().getStyle().clearProperty("overflow");
                    if (panel.getContent() != null) {
                        panel.getContent().setVisible(true);
                    }
                } else {
                    panel.contentPanel.getElement().getStyle().setProperty("overflow", "hidden");
                }
            }
        }

        @Override
        protected void onComplete() {
            if (!opening) {
                curPanel.contentPanel.setVisible(false);
                curPanel.updateStyles();
            } else {
                curPanel.contentPanel.getElement().getStyle().clearProperty("overflow");
                curPanel.contentPanel.getElement().getStyle().setDisplay(Display.INLINE_BLOCK);
            }
            curPanel.contentPanel.getElement().getStyle().setProperty("height", "auto");
            curPanel = null;
        }

        @Override
        protected void onStart() {
            super.onStart();
            if (opening) {
                curPanel.updateStyles();
                curPanel.contentPanel.setVisible(true);
                curPanel.contentPanel.getElement().getStyle().setDisplay(Display.INLINE_BLOCK);
                if (curPanel.getContent() != null) {
                    curPanel.getContent().setVisible(true);
                }
            } else {
                curPanel.contentPanel.getElement().getStyle().setProperty("overflow", "hidden");
            }
        }

        @Override
        protected void onUpdate(double progress) {
            int scrollHeight = curPanel.contentPanel.getElement().getPropertyInt("scrollHeight");
            int height = (int) (progress * scrollHeight);
            if (!opening) {
                height = scrollHeight - height;
            }
            height = Math.max(height, 1);
            curPanel.contentPanel.getElement().getStyle().setProperty("height", height + "px");
        }
    }

}