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

org.jhotdraw8.draw.figure.AbstractDrawing Maven / Gradle / Ivy

/*
 * @(#)AbstractDrawing.java
 * Copyright © 2023 The authors and contributors of JHotDraw. MIT License.
 */
package org.jhotdraw8.draw.figure;

import javafx.collections.ObservableList;
import javafx.css.StyleOrigin;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Rectangle;
import javafx.scene.transform.Transform;
import org.jhotdraw8.css.manager.SimpleStylesheetsManager;
import org.jhotdraw8.css.manager.StylesheetsManager;
import org.jhotdraw8.css.value.CssSize;
import org.jhotdraw8.draw.css.model.FigureSelectorModel;
import org.jhotdraw8.draw.css.value.CssRectangle2D;
import org.jhotdraw8.draw.css.value.Paintable;
import org.jhotdraw8.draw.render.RenderContext;
import org.jhotdraw8.fxcollection.typesafekey.Key;
import org.jhotdraw8.icollection.immutable.ImmutableList;
import org.jspecify.annotations.Nullable;

import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * DrawingFigure.
 *
 * @author Werner Randelshofer
 */
public abstract class AbstractDrawing extends AbstractCompositeFigure
        implements Drawing {

    /**
     * The style manager is created lazily.
     */
    private @Nullable StylesheetsManager
styleManager = null; public AbstractDrawing() { } public AbstractDrawing(double width, double height) { this(CssSize.of(width), CssSize.of(height)); } public AbstractDrawing(CssSize width, CssSize height) { set(WIDTH, width); set(HEIGHT, height); } @Override public Node createNode(RenderContext drawingView) { Pane g = new Pane(); g.setManaged(false); Group gg = new Group(); gg.setManaged(false); g.getChildren().add(gg); return g; } protected StylesheetsManager
createStyleManager() { return new SimpleStylesheetsManager<>(new FigureSelectorModel()); } /** * The bounds of this drawing is determined by its {@code WIDTH} and its * {@code HEIGHT}. *

* The bounds of the child figures does not affect the bounds of the * drawing. * * @return bounding box (0, 0, WIDTH, HEIGHT). */ @Override public CssRectangle2D getCssLayoutBounds() { return new CssRectangle2D(CssSize.ZERO, CssSize.ZERO, getStyledNonNull(WIDTH), getStyledNonNull(HEIGHT)); } @Override public Bounds getLayoutBounds() { // Note: We must override getBoundsInLocal of AbstractCompositeFigure. return getCssLayoutBounds().getConvertedBoundsValue(); } @Override public @Nullable StylesheetsManager

getStyleManager() { if (styleManager == null) { styleManager = createStyleManager(); updateStyleManager(); } return styleManager; } @Override public void updateStyleManager() { if (styleManager != null) { styleManager.setStylesheets(StyleOrigin.USER_AGENT, get(DOCUMENT_HOME), getList(USER_AGENT_STYLESHEETS)); styleManager.setStylesheets(StyleOrigin.AUTHOR, get(DOCUMENT_HOME), getList(AUTHOR_STYLESHEETS)); styleManager.setStylesheets(StyleOrigin.INLINE, getStringList(INLINE_STYLESHEETS)); } } private List getList(Key> key) { ImmutableList list = get(key); return list == null ? Collections.emptyList() : list.asList(); } private List getStringList(Key> key) { ImmutableList list = get(key); return list == null ? Collections.emptyList() : list.asList(); } @Override public void reshapeInLocal(Transform transform) { Bounds b = getLayoutBounds(); b = transform.transform(b); reshapeInLocal(b.getMinX(), b.getMinY(), b.getWidth(), b.getHeight()); } @Override public void reshapeInLocal(CssSize x, CssSize y, CssSize width, CssSize height) { set(WIDTH, width.abs()); set(HEIGHT, height.abs()); } @Override public void stylesheetChanged(RenderContext ctx) { if (styleManager != null) { styleManager.setStylesheets(StyleOrigin.USER_AGENT, get(DOCUMENT_HOME), getList(USER_AGENT_STYLESHEETS)); styleManager.setStylesheets(StyleOrigin.AUTHOR, get(DOCUMENT_HOME), getList(AUTHOR_STYLESHEETS)); styleManager.setStylesheets(StyleOrigin.INLINE, getStringList(INLINE_STYLESHEETS)); } super.stylesheetChanged(ctx); } @Override public void updateNode(RenderContext ctx, Node n) { Pane g = (Pane) n; Bounds bounds = getLayoutBounds(); g.setPrefWidth(bounds.getWidth()); g.setPrefHeight(bounds.getHeight()); g.resizeRelocate( bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), bounds.getHeight()); updateBackground(ctx, g); g.setClip(new Rectangle(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), bounds.getHeight())); Group gg = (Group) g.getChildren().getFirst(); List nodes = new ArrayList<>(getChildren().size()); for (Figure child : getChildren()) { nodes.add(ctx.getNode(child)); } ObservableList group = gg.getChildren(); if (!group.equals(nodes)) { group.setAll(nodes); } } public void updateBackground(RenderContext ctx, Pane g) { Paint paint = Paintable.getPaint(getStyled(BACKGROUND)); if ((paint instanceof Color) && ((Color) paint).getOpacity() == 0) { paint = null; } g.setBackground(paint == null ? null : new Background(new BackgroundFill( paint, CornerRadii.EMPTY, Insets.EMPTY))); } @Override public boolean isSuitableParent(Figure newParent) { return true; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy