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

com.guigarage.responsive.ResponsiveHandler Maven / Gradle / Ivy

package com.guigarage.responsive;

import java.util.List;
import javafx.beans.InvalidationListener;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ObjectPropertyBase;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.scene.Node;
import javafx.stage.Window;

import javafx.beans.property.BooleanProperty;
import javafx.css.PseudoClass;


public class ResponsiveHandler {

   private static String PROP_MANAGED_STATE = "responsivefx-preset-managed-state";

    private static InvalidationListener MANAGED_LISTENER = e -> {
        BooleanProperty managed = (BooleanProperty) e;
        Node node = (Node) managed.getBean();
        node.getProperties().put(PROP_MANAGED_STATE, node.isManaged());
    };

    public static void addResponsiveToWindow(Window window) {
        StringProperty stylesheet = new SimpleStringProperty(getCurrentResponsiveStylesheet(window));
        Util.bindStyleSheetToWindow(window, stylesheet);

        updatePseudoClassesForAllChildren(window);
        //TODO: Falsch! Hier muss der ursprünglich gesetzte Wert gespeichert werden! managed müsste eine styledProperty sein
        updateManagedPropertyForAllChildren(window);

        Util.registerRecursiveChildObserver(window, n -> removeAllPseudoClasses(n), n -> updatePseudoClasses(n, getTypeForWindow(window)));

        window.widthProperty().addListener(e -> {
            stylesheet.setValue(getCurrentResponsiveStylesheet(window));
            updatePseudoClassesForAllChildren(window);
            updateManagedPropertyForAllChildren(window);
        });
        window.getScene().getRoot().layout();
    }

    private static DeviceType getTypeForWindow(Window window) {
        return DeviceType.getForWidth(window.getWidth());
    }

    private static String getCurrentResponsiveStylesheet(Window window) {
        return getTypeForWindow(window).getStylesheet();
    }

    private static void updateManagedPropertyForAllChildren(Window window) {
        for (Node n : Util.getAllNodesInWindow(window)) {
            updateManagedProperty(n, getTypeForWindow(window));
        }
    }

    private static void updateManagedProperty(Node n, DeviceType type) {
        // first time we've set this invisible => store the preset
        if (!n.getProperties().containsKey(PROP_MANAGED_STATE)) {
            n.getProperties().put(PROP_MANAGED_STATE, n.isManaged());
        }
        // don't track changes through this
        n.managedProperty().removeListener(MANAGED_LISTENER);
        // If it's visible we use the stored value for "managed" property
        n.setManaged(n.isVisible() ? (Boolean) n.getProperties().get(PROP_MANAGED_STATE) : false);
        // need to track changes through API
        n.managedProperty().addListener(MANAGED_LISTENER);
    }

    private static void updatePseudoClassesForAllChildren(Window window) {
        List nodes = Util.getAllNodesInWindow(window);
        for (Node node : nodes) {
            updatePseudoClasses(node, getTypeForWindow(window));

        }
    }

    private static void updatePseudoClasses(Node n, DeviceType type) {
        for (PseudoClass pseudoClass : type.getInactiveClasses()) {
            n.pseudoClassStateChanged(pseudoClass, false);
        }
        for (PseudoClass pseudoClass : type.getActiveClasses()) {
            n.pseudoClassStateChanged(pseudoClass, true);
        }
        deviceTypeProperty.set(type);
    }

    private static void removeAllPseudoClasses(Node n) {
        for (PseudoClass pseudoClass : DeviceType.getAllClasses()) {
            n.pseudoClassStateChanged(pseudoClass, false);
        }
    }

    // ******************** Event handling *************************************
    public static final ObjectProperty deviceTypeProperty = new ObjectPropertyBase(DeviceType.NONE) {
        @Override
        public Object getBean() {
            return this;
        }

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

    public static final void setOnDeviceTypeChanged(final InvalidationListener LISTENER) {
        deviceTypeProperty.addListener(LISTENER);
    }

    public static final void setOnDeviceTypeChanged(final ChangeListener LISTENER) {
        deviceTypeProperty.addListener(LISTENER);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy