Search in sources :

Example 6 with DockPane

use of org.phoebus.ui.docking.DockPane in project phoebus by ControlSystemStudio.

the class MementoHelper method closePaneOrSplit.

/**
 * Close a DockPane or SplitDock and all tabs held within.
 *
 *  <p>Dock items must have been prepared to close.
 *
 *  @param node Node, either a dock item or split pane, that will be closed.
 *  @return boolean <code>true</code> if all the tabs close successfully.
 */
public static boolean closePaneOrSplit(final Node node) {
    if (node instanceof DockPane) {
        // Close every dock item in the dock pane.
        final DockPane pane = (DockPane) node;
        final List<DockItem> items = pane.getDockItems();
        for (final DockItem item : items) item.close();
    } else if (node instanceof SplitDock) {
        final SplitDock split = (SplitDock) node;
        // We are altering the size of the list we are iterating over...
        final List<Node> items = new ArrayList<>(split.getItems());
        // If a node fails to close, return false.
        for (Node item : items) if (!closePaneOrSplit(item))
            return false;
        // and thus not triggering a merge..
        if (split.getItems().size() > 0)
            split.merge();
    } else {
        logger.log(Level.WARNING, "Cannot close " + node);
        return false;
    }
    return true;
}
Also used : DockPane(org.phoebus.ui.docking.DockPane) Node(javafx.scene.Node) SplitDock(org.phoebus.ui.docking.SplitDock) ArrayList(java.util.ArrayList) List(java.util.List) DockItem(org.phoebus.ui.docking.DockItem)

Example 7 with DockPane

use of org.phoebus.ui.docking.DockPane in project phoebus by ControlSystemStudio.

the class MementoHelper method savePaneOrSplit.

/**
 * @param memento
 *  @param item DockPane or SplitDock
 */
private static void savePaneOrSplit(final MementoTree memento, final Node node) {
    if (node instanceof DockPane) {
        final DockPane pane = (DockPane) node;
        final MementoTree pane_memento = memento.createChild(PANE);
        if (pane.isFixed())
            pane_memento.setBoolean(FIXED, true);
        if (pane.getName().length() > 0)
            pane_memento.setString(NAME, pane.getName());
        pane_memento.setNumber(SELECTED, pane.getSelectionModel().getSelectedIndex());
        for (DockItem item : pane.getDockItems()) saveDockItem(pane_memento, item);
    } else if (node instanceof SplitDock) {
        final SplitDock split = (SplitDock) node;
        final MementoTree split_memento = memento.createChild(SPLIT);
        split_memento.setNumber(POS, split.getDividerPosition());
        if (!split.isHorizontal())
            split_memento.setBoolean(HORIZONTAL, false);
        for (Node sub : split.getItems()) savePaneOrSplit(split_memento, sub);
    } else
        logger.log(Level.WARNING, "Cannot persist " + node);
}
Also used : DockPane(org.phoebus.ui.docking.DockPane) MementoTree(org.phoebus.framework.persistence.MementoTree) XMLMementoTree(org.phoebus.framework.persistence.XMLMementoTree) Node(javafx.scene.Node) SplitDock(org.phoebus.ui.docking.SplitDock) DockItem(org.phoebus.ui.docking.DockItem)

Example 8 with DockPane

use of org.phoebus.ui.docking.DockPane in project phoebus by ControlSystemStudio.

the class MementoHelper method restorePaneOrSplit.

/**
 * @param pane Initial, empty pane that might be filled with items or split
 *  @param children
 *  @return <code>true</code> if any tab item was restored
 */
private static boolean restorePaneOrSplit(final DockPane pane, final MementoTree content) {
    boolean any = false;
    if (content.getName().equals(PANE)) {
        // Fill given pane with tabs
        for (MementoTree item_memento : content.getChildren()) any |= restoreDockItem(item_memento, pane);
        // Maybe select a specific tab
        // If the new tab is inside a SplitDock,
        // it won't actually exist until the content of the SplitDock's SplitPane
        // is rendered on the next UI tick, resulting in a NullPointerException
        // deep inside JFX calling TabPane$TabPaneSelectionModel.select
        // By deferring to a later UI tick, the tab selection succeeds
        content.getNumber(SELECTED).ifPresent(index -> Platform.runLater(() -> {
            // so check once more
            if (index.intValue() < pane.getTabs().size())
                pane.getSelectionModel().select(index.intValue());
        }));
        content.getString(NAME).ifPresent(pane::setName);
        // If pane is 'fixed', mark as such _after_ all items have been restored
        // to prevent changes from now on
        content.getBoolean(FIXED).ifPresent(fixed -> {
            // then wait another tick
            if (fixed)
                Platform.runLater(() -> pane.deferUntilInScene(scene -> Platform.runLater(() -> pane.setFixed(true))));
        });
    } else if (content.getName().equals(SPLIT)) {
        // Split the original pane
        final SplitDock split = pane.split(content.getBoolean(HORIZONTAL).orElse(true));
        // Fill split's items
        final List<Node> first_second_pane = split.getItems();
        final List<MementoTree> first_second_mememto = content.getChildren();
        any |= restorePaneOrSplit((DockPane) first_second_pane.get(0), first_second_mememto.get(0));
        any |= restorePaneOrSplit((DockPane) first_second_pane.get(1), first_second_mememto.get(1));
        // The divider position needs to be set at the end, after the complete scene has been restored.
        // Otherwise the SplitPane self-adjusts the position when the sub-elements are rendered,
        // replacing a position set now.
        content.getNumber(POS).ifPresent(num -> {
            UpdateThrottle.TIMER.schedule(() -> Platform.runLater(() -> split.setDividerPosition(num.doubleValue())), 300, TimeUnit.MILLISECONDS);
        });
    } else
        logger.log(Level.WARNING, "Expect <pane> or <split>, got " + content);
    return any;
}
Also used : ApplicationService(org.phoebus.framework.workbench.ApplicationService) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) URI(java.net.URI) DockPane(org.phoebus.ui.docking.DockPane) PhoebusApplication.logger(org.phoebus.ui.application.PhoebusApplication.logger) DockItemWithInput(org.phoebus.ui.docking.DockItemWithInput) UpdateThrottle(org.phoebus.ui.javafx.UpdateThrottle) Rectangle2D(javafx.geometry.Rectangle2D) PhoebusApplication(org.phoebus.ui.application.PhoebusApplication) DockStage(org.phoebus.ui.docking.DockStage) MementoTree(org.phoebus.framework.persistence.MementoTree) AppInstance(org.phoebus.framework.spi.AppInstance) Node(javafx.scene.Node) FileOutputStream(java.io.FileOutputStream) AppDescriptor(org.phoebus.framework.spi.AppDescriptor) DockItem(org.phoebus.ui.docking.DockItem) Screen(javafx.stage.Screen) File(java.io.File) TimeUnit(java.util.concurrent.TimeUnit) Platform(javafx.application.Platform) SplitDock(org.phoebus.ui.docking.SplitDock) List(java.util.List) XMLMementoTree(org.phoebus.framework.persistence.XMLMementoTree) Stage(javafx.stage.Stage) AppResourceDescriptor(org.phoebus.framework.spi.AppResourceDescriptor) MementoTree(org.phoebus.framework.persistence.MementoTree) XMLMementoTree(org.phoebus.framework.persistence.XMLMementoTree) SplitDock(org.phoebus.ui.docking.SplitDock) ArrayList(java.util.ArrayList) List(java.util.List)

Example 9 with DockPane

use of org.phoebus.ui.docking.DockPane in project phoebus by ControlSystemStudio.

the class MementoHelper method restoreStage.

/**
 * Restore state of Stage from memento
 *  @param memento
 *  @param stage
 *  @return <code>true</code> if any tab item was restored
 */
public static boolean restoreStage(final MementoTree stage_memento, final Stage stage) {
    // Closest to atomically setting size and location with minimal flicker: hide, update, show
    stage.hide();
    stage_memento.getNumber(X).ifPresent(num -> stage.setX(num.doubleValue()));
    stage_memento.getNumber(Y).ifPresent(num -> stage.setY(num.doubleValue()));
    stage_memento.getNumber(WIDTH).ifPresent(num -> stage.setWidth(num.doubleValue()));
    stage_memento.getNumber(HEIGHT).ifPresent(num -> stage.setHeight(num.doubleValue()));
    // Check if stage is visible.
    // Memento might have been stored when a secondary monitor was connected
    // or on a different host with larger display, but saved location is outside
    // of currently connected displays.
    // Mac OS might relocate them on its own,
    // but at least in Windows 10 such stages are then off-screen and hard to get.
    final List<Screen> match = Screen.getScreensForRectangle(stage.getX(), stage.getY(), stage.getWidth(), stage.getHeight());
    if (match.isEmpty()) {
        logger.log(Level.WARNING, "Relocating restored stage from X=" + stage.getX() + " Y=" + stage.getY() + " to primary screen");
        final Rectangle2D relocate = Screen.getPrimary().getVisualBounds();
        // Move to top-left corner of primary screen so it's visible.
        // Keep size to minimize impact on saved layout.
        stage.setX(relocate.getMinX());
        stage.setY(relocate.getMinY());
    }
    stage.show();
    stage_memento.getBoolean(FULLSCREEN).ifPresent(flag -> stage.setFullScreen(flag));
    stage_memento.getBoolean(MAXIMIZED).ifPresent(flag -> stage.setMaximized(flag));
    stage_memento.getBoolean(MINIMIZED).ifPresent(flag -> stage.setIconified(flag));
    // Initial pane of the new stage
    final DockPane pane = DockStage.getDockPanes(stage).get(0);
    // <pane> content or <split>
    final List<MementoTree> children = stage_memento.getChildren();
    if (children.size() != 1) {
        logger.log(Level.WARNING, "Expect single <pane> or <split>, got " + children);
        return false;
    }
    return restorePaneOrSplit(pane, children.get(0));
}
Also used : Screen(javafx.stage.Screen) DockPane(org.phoebus.ui.docking.DockPane) MementoTree(org.phoebus.framework.persistence.MementoTree) XMLMementoTree(org.phoebus.framework.persistence.XMLMementoTree) Rectangle2D(javafx.geometry.Rectangle2D)

Aggregations

DockPane (org.phoebus.ui.docking.DockPane)9 Node (javafx.scene.Node)4 Stage (javafx.stage.Stage)4 DockStage (org.phoebus.ui.docking.DockStage)4 File (java.io.File)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 MementoTree (org.phoebus.framework.persistence.MementoTree)3 XMLMementoTree (org.phoebus.framework.persistence.XMLMementoTree)3 AppResourceDescriptor (org.phoebus.framework.spi.AppResourceDescriptor)3 DockItem (org.phoebus.ui.docking.DockItem)3 DockItemWithInput (org.phoebus.ui.docking.DockItemWithInput)3 SplitDock (org.phoebus.ui.docking.SplitDock)3 FileInputStream (java.io.FileInputStream)2 URI (java.net.URI)2 TimeUnit (java.util.concurrent.TimeUnit)2 Level (java.util.logging.Level)2 Platform (javafx.application.Platform)2 Rectangle2D (javafx.geometry.Rectangle2D)2 Alert (javafx.scene.control.Alert)2