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

org.drombler.commons.docking.fx.impl.DockingAreaPane Maven / Gradle / Ivy

There is a newer version: 1.0
Show newest version
/*
 *         COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Notice
 *
 * The contents of this file are subject to the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.opensource.org/licenses/cddl1.txt
 *
 * The Original Code is Drombler.org. The Initial Developer of the
 * Original Code is Florian Brunner (Sourceforge.net user: puce).
 * Copyright 2012 Drombler.org. All Rights Reserved.
 *
 * Contributor(s): .
 */
package org.drombler.commons.docking.fx.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.SingleSelectionModel;
import org.drombler.commons.docking.DockingAreaKind;
import org.drombler.commons.docking.LayoutConstraintsDescriptor;
import org.drombler.commons.docking.fx.FXDockableEntry;
import org.drombler.commons.docking.fx.impl.skin.Stylesheets;
import org.drombler.commons.docking.spi.DockingArea;
import org.drombler.commons.docking.spi.DockingAreaManager;
import org.drombler.commons.docking.spi.DockingAreaUtils;
import org.drombler.commons.docking.spi.ShortPathPart;
import org.drombler.commons.fx.scene.control.ListSingleSelectionModel;
import org.softsmithy.lib.util.PositionableAdapter;
import org.softsmithy.lib.util.Positionables;

/**
 *
 * @author puce
 */
public class DockingAreaPane extends DockingSplitPaneChildBase implements DockingArea {

    private static final String DEFAULT_STYLE_CLASS = "docking-area-pane";
    /**
     * The area ID.
     */
    private final String areaId;
    private final ObservableList> dockables = FXCollections.observableArrayList();
    private final ObservableList> unmodifiableDockables = FXCollections.
            unmodifiableObservableList(dockables);
    private final Set dockableSet = new HashSet<>();
    private final DockingAreaKind kind;
    private final int position;
    /**
     * Flag if the space for this docking area should be preserved, if it's empty, or if it's space should be freed.
     */
    private final boolean permanent;
    private DockingAreaManager parentManager;
    /**
     * Flag if this DockingArea has been added to a {@link DockingSplitPane} already.
     */
    private final BooleanProperty visualized = new SimpleBooleanProperty(this, "visualized", false);
    private final ObjectProperty>> selectionModel
            = new SimpleObjectProperty<>(this, "singleSelectionModel", new ListSingleSelectionModel<>(dockables));

    public DockingAreaPane(String areaId, DockingAreaKind kind, int position, boolean permanent,
            LayoutConstraintsDescriptor layoutConstraints) {
        super(false);
        this.areaId = areaId;
        this.kind = kind;
        this.position = position;
        this.permanent = permanent;
        setLayoutConstraints(layoutConstraints);
        getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue)
                -> DockingAreaUtils.onSelectionChanged(oldValue, newValue));
        getStyleClass().setAll(DEFAULT_STYLE_CLASS);
    }

    @Override
    public String getUserAgentStylesheet() {
        return Stylesheets.getDefaultStylesheet();
    }

    /**
     * @return the areaId
     */
    public String getAreaId() {
        return areaId;
    }

    public DockingAreaKind getKind() {
        return kind;
    }

    @Override
    public int getPosition() {
        return position;
    }

    public final boolean isVisualized() {
        return visualizedProperty().get();
    }

    public final void setVisualized(boolean visualized) {
        visualizedProperty().set(visualized);
    }

    public BooleanProperty visualizedProperty() {
        return visualized;
    }

    public final SingleSelectionModel> getSelectionModel() {
        return singleModelProperty().get();
    }

    public final void setSelectionModel(SingleSelectionModel> selectionModel) {
        singleModelProperty().set(selectionModel);
    }

    public ObjectProperty>> singleModelProperty() {
        return selectionModel;
    }

    public boolean addDockable(PositionableAdapter dockable) {
        if (!containsDockable(dockable.getAdapted())) {
            dockableSet.add(dockable.getAdapted());
            int insertionPoint = Positionables.getInsertionPoint(dockables, dockable);
            dockables.add(insertionPoint, dockable);
            return true;
        } else {
            return false;
        }
    }

    public boolean containsDockable(FXDockableEntry dockableEntry) {
        return dockableSet.contains(dockableEntry);
    }

    public PositionableAdapter removeDockable(int index) {
        PositionableAdapter dockable = dockables.remove(index);
        dockableSet.remove(dockable.getAdapted());
        return dockable;
    }

    public boolean removeDockable(FXDockableEntry dockableEntry) {
        if (containsDockable(dockableEntry)) {
            dockableSet.remove(dockableEntry);
            dockables.removeIf(adapter -> adapter.getAdapted().equals(dockableEntry));
            return true;
        } else {
            return false;
        }
    }

    /**
     * @return the dockablePanes
     */
    public ObservableList> getDockables() {
        return unmodifiableDockables;
    }

    /**
     * @return the permanent
     */
    public boolean isPermanent() {
        return permanent;
    }

    @Override
    public void setParentManager(DockingAreaManager parentManager) {
        this.parentManager = parentManager;
    }

    /**
     * Gets the short path.
     *
     * The short path is the path without any unnecessary split panes.
     *
     * @return a {@link List} of {@link ShortPathPart}s forming the short path.
     */
    public List getShortPath() {
        return parentManager.getShortPath(this);
    }

    /**
     * Indicates if this DockingAreaPane is either {@link #isPermanent()} or non-empty.
     *
     * @return returns true if permanent or non-empty.
     */
    //TODO: good name?
    public boolean isVisualizable() {
        return isPermanent() || !getDockables().isEmpty();
    }

    // when the last dockable is beeing removed from the docking area, 
    // the docking area is not visualizable (empty) but still visualized 
    // (child of a DockingSplitPane; and thus has to be removed from it)
    //TODO: good name?
    @Override
    public boolean isVisual() {
        return isVisualizable() || isVisualized();
    }

    @Override
    public void updateLayoutConstraints() {
        if (LayoutConstraintsDescriptor.isPreferred(getLayoutConstraints().getPrefWidth())) {
            getLayoutConstraints().setPrefWidth(getWidth());
        }
        if (LayoutConstraintsDescriptor.isPreferred(getLayoutConstraints().getPrefHeight())) {
            getLayoutConstraints().setPrefHeight(getHeight());
        }
    }

    @Override
    public String toString() {
        return DockingAreaPane.class.getSimpleName() + "[areaId=" + areaId
                + ", kind=" + kind + ", position=" + position + ", permanent=" + permanent
                + ", visuablizable=" + isVisualizable()
                + ", visualized=" + isVisualized() + "]";
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy