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

org.dominokit.domino.ui.modals.Window Maven / Gradle / Ivy

There is a newer version: 1.0.139
Show newest version
package org.dominokit.domino.ui.modals;

import elemental2.dom.ClientRect;
import elemental2.dom.DomGlobal;
import elemental2.dom.EventListener;
import elemental2.dom.MouseEvent;
import jsinterop.base.Js;
import org.dominokit.domino.ui.grid.flex.FlexItem;
import org.dominokit.domino.ui.grid.flex.FlexLayout;
import org.dominokit.domino.ui.icons.Icons;
import org.dominokit.domino.ui.icons.MdiIcon;
import org.dominokit.domino.ui.style.Color;
import org.jboss.elemento.EventType;

import static org.dominokit.domino.ui.style.Unit.px;

public class Window extends BaseModal {

    private final MdiIcon restoreIcon;
    private final MdiIcon maximizeIcon;
    private final MdiIcon closeIcon;
    private boolean maximized = false;

    private double mouseX;
    private double mouseY;

    private boolean startMoving = false;
    private double deltaX;
    private double deltaY;
    private final EventListener moveListener;
    private final EventListener stopMoveListener;

    private double windowLeft = -1;
    private double windowTop = -1;

    private String headerBackGround = Color.THEME.getBackground();

    private boolean draggable = true;
    private boolean fixed;

    public static Window create(String title) {
        return new Window(title);
    }

    public Window(String title) {
        super(title);
        init(this);
        elevate(10);
        setModal(false);
        css("window");
        modalElement.getModalHeader().css(headerBackGround);
        modalElement.getModalTitle().styler(style -> style
                .setFloat("left")
                .setPadding(px.of(8)));

        restoreIcon = Icons.ALL.window_restore_mdi();
        maximizeIcon = Icons.ALL.window_maximize_mdi();
        closeIcon = Icons.ALL.close_mdi();
        modalElement.getModalHeader().appendChild(FlexLayout.create()
                .styler(style -> style.setFloat("right"))
                .appendChild(FlexItem.create()
                        .appendChild(restoreIcon
                                .hide()
                                .size18()
                                .clickable()
                                .addClickListener(evt -> restore())
                        )
                        .appendChild(maximizeIcon
                                .size18()
                                .clickable()
                                .addClickListener(evt -> maximize())
                        )
                        .appendChild(closeIcon
                                .size18()
                                .clickable()
                                .addClickListener(evt -> close()))
                )
        );

        moveListener = evt -> {

            if (draggable) {
                MouseEvent mouseEvent = Js.uncheckedCast(evt);

                if (startMoving && mouseEvent.button == 0 && !maximized) {
                    evt.preventDefault();
                    deltaX = mouseX - mouseEvent.clientX;
                    deltaY = mouseY - mouseEvent.clientY;
                    mouseX = mouseEvent.clientX;
                    mouseY = mouseEvent.clientY;

                    double left = modalElement.element().offsetLeft - deltaX;
                    double top = modalElement.element().offsetTop - deltaY;

                    ClientRect windowRect = modalElement.getModalDialog().element().getBoundingClientRect();
                    double initialWidth = windowRect.width;
                    double initialHeight = windowRect.height;

                    double windowWidth = DomGlobal.window.innerWidth;
                    double windowHeight = DomGlobal.window.innerHeight;

                    if (left > 0 && left < (windowWidth - initialWidth)) {
                        modalElement.element().style.left = left + "px";
                        this.windowLeft = left;
                    }

                    if (top > 0 && top < (windowHeight - initialHeight)) {
                        modalElement.element().style.top = top + "px";
                        this.windowTop = top;
                    }
                }
            }
        };
        stopMoveListener = evt -> {
            if (draggable) {
                startMoving = false;
            }
        };

        addOpenListener(this::addMoveListeners);
        addCloseListener(this::removeMoveListeners);

        initPosition();
    }

    public boolean isDraggable() {
        return draggable;
    }

    public Window setDraggable(boolean draggable) {
        this.draggable = draggable;
        return this;
    }

    public Window maximize() {
        maximizeIcon.hide();
        restoreIcon.show();
        maximized = true;
        updatePosition();
        Window.this.css("maximized");

        return this;
    }

    public Window restore() {
        restoreIcon.hide();
        maximizeIcon.show();
        maximized = false;
        Window.this.removeCss("maximized");
        updatePosition();

        return this;
    }

    public Window setHeaderBackground(Color color) {
        modalElement.getModalHeader().removeCss(headerBackGround);
        modalElement.getModalHeader().css(color.getBackground());
        this.headerBackGround = color.getBackground();

        return this;
    }

    public Window setFixed() {
        css("fixed");
        this.fixed = true;
        updatePosition();
        return this;
    }

    public boolean isMaximized() {
        return maximized;
    }

    public double getWindowLeft() {
        return windowLeft;
    }

    public Window setWindowLeft(double windowLeft) {
        this.windowLeft = windowLeft;
        return this;
    }

    public double getWindowTop() {
        return windowTop;
    }

    public Window setWindowTop(double windowTop) {
        this.windowTop = windowTop;
        return this;
    }

    private void initPosition() {
        onOpen(this::updatePosition);
    }

    private void updatePosition() {
        if (maximized) {
            modalElement.element().style.left = "0px";
            modalElement.element().style.top = "0px";
        } else {
            ClientRect windowRect = modalElement.getModalDialog().element().getBoundingClientRect();
            double initialWidth = windowRect.width;
            double windowWidth = DomGlobal.window.innerWidth;

            if (windowLeft < 0) {
                modalElement.element().style.left = ((windowWidth - initialWidth) / 2) + ((fixed ? 0 : DomGlobal.window.pageXOffset)) + "px";
            } else {
                modalElement.element().style.left = windowLeft + "px";
            }

            if (windowTop < 0) {
                modalElement.element().style.top = 100 + (fixed ? 0 : DomGlobal.window.pageYOffset) + "px";
            } else {
                modalElement.element().style.top = windowTop + "px";
            }
        }
    }

    private void removeMoveListeners() {
        DomGlobal.document.body.removeEventListener(EventType.mouseup.getName(), stopMoveListener);
        DomGlobal.document.body.removeEventListener(EventType.mousemove.getName(), moveListener);
        modalElement.getModalHeader().removeEventListener(EventType.mousemove.getName(), moveListener);
        modalElement.getModalHeader().removeEventListener(EventType.mouseup.getName(), stopMoveListener);
    }

    private void addMoveListeners() {
        modalElement.getModalHeader()
                .addEventListener(EventType.mousedown, evt -> {
                    if (draggable) {
                        MouseEvent mouseEvent = Js.uncheckedCast(evt);
                        if (!startMoving && mouseEvent.button == 0) {
                            mouseEvent.stopPropagation();
                            mouseEvent.preventDefault();

                            mouseX = mouseEvent.clientX;
                            mouseY = mouseEvent.clientY;

                            startMoving = true;
                        }
                    }
                });

        modalElement.getModalHeader()
                .addEventListener(EventType.mouseup, stopMoveListener);
        DomGlobal.document.body
                .addEventListener(EventType.mousemove.getName(), moveListener);
        DomGlobal.document.body
                .addEventListener(EventType.mouseup.getName(), stopMoveListener);
    }

    public Window hideResizing() {
        restoreIcon.hide();
        maximizeIcon.hide();
        return this;
    }

    public Window showResizing() {
        if (maximized) {
            maximizeIcon.hide();
            restoreIcon.show();
        } else {
            maximizeIcon.show();
            restoreIcon.hide();
        }
        return this;
    }

    public Window hideClosing() {
        closeIcon.hide();
        return this;
    }

    public Window showClosing() {
        closeIcon.show();
        return this;
    }

    public MdiIcon getRestoreIcon() {
        return restoreIcon;
    }

    public MdiIcon getMaximizeIcon() {
        return maximizeIcon;
    }

    public MdiIcon getCloseIcon() {
        return closeIcon;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy