All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ikasan.dashboard.ui.scheduler.component.CollapsableLayout Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
package org.ikasan.dashboard.ui.scheduler.component;

import com.vaadin.flow.component.ClickEvent;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.ComponentEvent;
import com.vaadin.flow.component.ComponentEventListener;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.shared.Registration;

public class CollapsableLayout extends VerticalLayout {

    private HorizontalLayout header;
    private Div content;
    boolean collapseOnHeaderClick = false;

    /**
     * Creates a new Collapsable layout that will start collapsed.
     */
    public CollapsableLayout() {
        this(false);
    }

    /**
     * Creates a new collapsable layout that will start in the mode given.
     *
     * @param startVisible true starts with content hidden, false starts with content shown
     */
    public CollapsableLayout(boolean startVisible) {
        setWidthFull();
        setSpacing(false);
        setMargin(false);
        setPadding(false);

        header = new HorizontalLayout();
        header.setWidthFull();
        header.setSpacing(false);
        header.setPadding(false);
        header.setMargin(false);
        header.setDefaultVerticalComponentAlignment(Alignment.CENTER);
        header.setHeight("40px");
        header.getStyle().set("border-bottom", "1px solid #eee");

        content = new Div();
        content.setWidthFull();
        content.setVisible(startVisible);

        header.addClickListener(this::onHeaderClick);
        addClassName("collapsable-layout");
        header.addClassName("collapsable-layout-header");
        content.addClassName("collapsable-layout-content");

        add(header);
        addAndExpand(content);

        this.getElement().getStyle().remove("height");
    }

    protected void onHeaderClick(ClickEvent horizontalLayoutClickEvent) {
        if (collapseOnHeaderClick) {
            toggleContentVisibility();
        }
    }

    /**
     * Is the layout set to collapse when the header is clicked.
     *
     * @return true header clicks toggle state, false header clicks do not toggle state.
     */
    public boolean isCollapseOnHeaderClick() {
        return collapseOnHeaderClick;
    }

    /**
     * Enable or disable the header click toggles collapsed state function.
     *
     * @param collapseOnHeaderClick true header clicks toggle state, false header clicks do not toggle state.
     */
    public void setCollapseOnHeaderClick(boolean collapseOnHeaderClick) {
        this.collapseOnHeaderClick = collapseOnHeaderClick;
    }

    /**
     * Toggle the current visiblity state programmatically.
     */
    public void toggleContentVisibility() {
        boolean previousVisiblity = getContent().isVisible();
        content.setVisible(!content.isVisible());
        internalFireCollapsedStateEvent(previousVisiblity);
    }

    protected void internalFireCollapsedStateEvent(boolean previousVisiblity) {
        fireEvent(new CollapseChangedEvent(this, false, previousVisiblity, content.isVisible()));
    }

    /**
     * Explicitly set the visibility state. Note does not fire events.
     *
     * @param visible true content should be visible, false content should be hidden.
     */
    public void setContentVisible(boolean visible) {
        setContentVisible(visible, false);
    }

    /**
     * Explicitly set the visibility state
     *
     * @param visible    true content should be visible, false content should be hidden.
     * @param fireEvents true fire collapse state change event, false do not fire events.
     */
    public void setContentVisible(boolean visible, boolean fireEvents) {
        boolean previousVisibility = getContent().isVisible();

        content.setVisible(visible);

        if (fireEvents) {
            internalFireCollapsedStateEvent(previousVisibility);
        }
    }

    /**
     * Returns the current content visiblity state.
     *
     * @return true content is visible, false content is hidden
     */
    public boolean isContentVisible() {
        return content.isVisible();
    }

    /**
     * Adds a header component.
     *
     * @param component the component to add.
     */
    public void addHeaderComponent(Component... component) {
        getHeader().add(component);
    }

    /**
     * Removes a header component.
     *
     * @param component the component to remove.
     */
    public void removeHeaderComponent(Component... component) {
        getHeader().remove(component);
    }

    /**
     * Adds a header component as last (in the current set of components) and adds a margin that will push it to the far right.
     *
     * @param component the component to add
     */
    public void addHeaderComponentAsLastAndAlignToRight(Component component) {
        getHeader().addComponentAtIndex(getHeader().getComponentCount(), component);
        component.getElement().getStyle().set("margin-left", "auto");
    }

    /**
     * Adds a component to the content area.
     *
     * @param component the component to add.
     */
    public void addContentComponent(Component... component) {
        getContent().add(component);
    }

    /**
     * Removes a component from the content area.
     *
     * @param component the component to remove.
     */
    public void removeContentComponent(Component... component) {
        getContent().remove(component);
    }

    /**
     * Adds a listener that is triggrered when the visiblity state of the content changes.
     *
     * @param listener the listener to add
     * @return the registration for managing the listener.
     */
    public Registration addCollapseChangeListener(CollapsableLayoutCollapseStateListener listener) {
        return addListener(CollapseChangedEvent.class, listener);
    }

    //Returns the content, override to change.
    protected Div getContent() {
        return content;
    }

    //Returns the header, override to change.
    protected HorizontalLayout getHeader() {
        return header;
    }

    /**
     * The interface to listen for collapse change events.
     */
    public interface CollapsableLayoutCollapseStateListener extends ComponentEventListener {

        @Override
        void onComponentEvent(CollapseChangedEvent event);
    }

    /**
     * The event that is fired when the collapse state changes.
     */
    public static class CollapseChangedEvent extends ComponentEvent {

        private boolean wasVisible;
        private boolean currentlyVisible;

        public CollapseChangedEvent(CollapsableLayout source, boolean fromClient, boolean wasVisible, boolean currentlyVisible) {
            super(source, fromClient);
            this.wasVisible = wasVisible;
            this.currentlyVisible = currentlyVisible;
        }

        public boolean isWasVisible() {
            return wasVisible;
        }

        public boolean isCurrentlyVisible() {
            return currentlyVisible;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy