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

org.bidib.wizard.dmx.client.view.DmxSceneryView Maven / Gradle / Ivy

The newest version!
package org.bidib.wizard.dmx.client.view;

import java.awt.Component;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;

import org.bidib.wizard.api.locale.Resources;
import org.bidib.wizard.api.model.NodeInterface;
import org.bidib.wizard.client.common.view.DockKeys;
import org.bidib.wizard.client.common.view.listener.TabStatusListener;
import org.bidib.wizard.common.labels.WizardLabelWrapper;
import org.bidib.wizard.common.service.SettingsService;
import org.bidib.wizard.common.utils.ImageUtils;
import org.bidib.wizard.dmx.client.controller.listener.DmxModelerControllerListener;
import org.bidib.wizard.dmx.client.model.DmxSceneryModel;
import org.bidib.wizard.dmx.client.view.scenery.SceneryTreePanel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vlsolutions.swing.docking.DockKey;
import com.vlsolutions.swing.docking.DockTabbedPane;
import com.vlsolutions.swing.docking.Dockable;
import com.vlsolutions.swing.docking.DockableState;
import com.vlsolutions.swing.docking.DockingDesktop;
import com.vlsolutions.swing.docking.DockingUtilities;
import com.vlsolutions.swing.docking.event.DockableSelectionEvent;
import com.vlsolutions.swing.docking.event.DockableSelectionListener;
import com.vlsolutions.swing.docking.event.DockableStateChangeEvent;
import com.vlsolutions.swing.docking.event.DockableStateChangeListener;

import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;

/**
 * The DmxSceneryView is the view that shows the list of the DmxScenery instances that are
 * currently loaded.
 */
public class DmxSceneryView implements Dockable {
    private static final Logger LOGGER = LoggerFactory.getLogger(DmxSceneryView.class);

    private JComponent sceneryPanel;

    private final DmxSceneryModel dmxSceneryModel;

    private final NodeInterface node;

    private final DmxModelerControllerListener dmxModelerControllerListener;

    private final SettingsService settingsService;

    private WizardLabelWrapper wizardLabelWrapper;

    private SceneryTreePanel sceneryTreePanel;

    private final CompositeDisposable compDisp;

    private final TabStatusListener tabStatusListener;

    private final DockableStateChangeListener dockableStateChangeListener;

    private final AtomicBoolean focusListenerAdded = new AtomicBoolean();

    private final DmxToolBarProvider dmxToolbarProvider;

    public DmxSceneryView(final DockingDesktop desktop, final NodeInterface node, final DmxSceneryModel dmxSceneryModel,
        final SettingsService settingsService, final WizardLabelWrapper wizardLabelWrapper,
        final DmxModelerControllerListener dmxModelerControllerListener, final DmxToolBarProvider dmxToolbarProvider) {
        this.dmxSceneryModel = dmxSceneryModel;
        this.node = node;
        this.settingsService = settingsService;
        this.wizardLabelWrapper = wizardLabelWrapper;
        this.dmxModelerControllerListener = dmxModelerControllerListener;
        this.dmxToolbarProvider = dmxToolbarProvider;

        this.compDisp = new CompositeDisposable();

        DockKeys.DOCKKEY_DMX_SCENERY_VIEW.setName(Resources.getString(DmxSceneryView.class, "title"));
        // turn off autohide and close features
        DockKeys.DOCKKEY_DMX_SCENERY_VIEW.setCloseEnabled(true);
        DockKeys.DOCKKEY_DMX_SCENERY_VIEW.setAutoHideEnabled(false);
        DockKeys.DOCKKEY_DMX_SCENERY_VIEW.setFloatEnabled(true);

        final FocusListener focusListener = new FocusListener() {

            @Override
            public void focusLost(FocusEvent e) {
                dmxToolbarProvider.setVisible(DmxSceneryView.this, false);
            }

            @Override
            public void focusGained(FocusEvent e) {
                dmxToolbarProvider.setVisible(DmxSceneryView.this, true);
            }
        };

        final ImageIcon pendingChangesIcon =
            ImageUtils.createImageIcon(DmxDimmerConfigView.class, "/icons/16x16/savetonode.png");
        this.tabStatusListener = new TabStatusListener() {

            @Override
            public void updatePendingChanges(Component source, boolean hasPendingChanges) {

                Icon icon = null;
                if (hasPendingChanges) {
                    icon = pendingChangesIcon;
                }

                DockKeys.DOCKKEY_DMX_SCENERY_VIEW.setIcon(icon);
                DockKeys.DOCKKEY_DMX_SCENERY_VIEW
                    .setTooltip(hasPendingChanges
                        ? Resources.getString(DmxSceneryView.class, "save_pending_changes.tooltip") : null);

                if (hasPendingChanges) {
                    // show the toolbar
                    dmxToolbarProvider.setVisible(DmxSceneryView.this, hasPendingChanges);
                    dmxToolbarProvider.setPendingChanges(DmxSceneryView.this, hasPendingChanges);
                }
            }
        };

        dockableStateChangeListener = new DockableStateChangeListener() {

            @Override
            public void dockableStateChanged(DockableStateChangeEvent event) {
                LOGGER
                    .info("The state has changed, newState: {}, prevState: {}", event.getNewState(),
                        event.getPreviousState());

                DockableState newState = event.getNewState();
                if (newState.getDockable().equals(DmxSceneryView.this) && newState.isClosed()) {
                    LOGGER.info("The DmxSceneryView is closed.");
                    // we are closed
                    desktop.removeDockableStateChangeListener(dockableStateChangeListener);

                    final Dockable dockable = DmxSceneryView.this;
                    DockTabbedPane dockTabbedPane =
                        (DockTabbedPane) DockingUtilities.findTabbedDockableContainer(dockable);
                    if (dockTabbedPane != null) {
                        dockTabbedPane.removeFocusListener(focusListener);
                    }

                    // hide the toolbar
                    dmxToolbarProvider.setVisible(dockable, false);

                }

            }
        };
        desktop.addDockableStateChangeListener(dockableStateChangeListener);

        // toolbarCvDefinition = new VLToolBar("readyDmxCvDefinition");
        // addToolBarButtons(toolbarCvDefinition);
        // addToolBar(toolbarCvDefinition, new ToolBarConstraints(0, 2));
        // // initially invisible
        // toolbarCvDefinition.setVisible(false);

        desktop.getContext().addDockableSelectionListener(new DockableSelectionListener() {

            @Override
            public void selectionChanged(DockableSelectionEvent e) {
                LOGGER.info("Received DockableSelectionEvent, current selected dockable: {}", e.getSelectedDockable());

                final Dockable selectedDockable = e.getSelectedDockable();
                if (DmxSceneryView.this.equals(selectedDockable)) {
                    LOGGER.info("The DmxSceneryView is selected.");

                    dmxToolbarProvider.setVisible(DmxSceneryView.this, true);
                }
                else {
                    LOGGER.info("The DmxSceneryView is not selected.");
                    // if (toolbarCvDefinition.isVisible()) {
                    // toolbarCvDefinition.setVisible(false);
                    dmxToolbarProvider.setVisible(DmxSceneryView.this, false);

                    // we must add a focus listener because otherwise we will not get notified if this dockable is
                    // already selected and "re-selected" when we come from another docking container
                    if (!focusListenerAdded.get()) {
                        Dockable dockable = DmxSceneryView.this;
                        DockTabbedPane dockTabbedPane =
                            (DockTabbedPane) DockingUtilities.findTabbedDockableContainer(dockable);
                        if (dockTabbedPane != null) {
                            dockTabbedPane.addFocusListener(focusListener);

                            focusListenerAdded.set(true);
                        }
                    }
                    // }
                }
            }
        });

        dmxToolbarProvider.setVisible(this, true);
    }

    public void createPanel() {
        LOGGER.info("Create the scenery panel.");

        this.sceneryTreePanel =
            new SceneryTreePanel(node, dmxModelerControllerListener, dmxSceneryModel, settingsService);

        this.sceneryPanel = this.sceneryTreePanel.createPanel();

        final Disposable disp = this.dmxSceneryModel.subscribeHasPendingChangesEvents(hasPendingChanges -> {
            LOGGER.info("Received hasPendingChanges: {}", hasPendingChanges);

            tabStatusListener
                .updatePendingChanges(this.sceneryPanel, hasPendingChanges != null ? hasPendingChanges : false);
            sceneryTreePanel.updatePendingChanges(hasPendingChanges != null ? hasPendingChanges : false);

            dmxToolbarProvider.setPendingChanges(DmxSceneryView.this, hasPendingChanges);

        }, th -> {
            LOGGER.warn("The dirty subscription signalled an error: {}", th);
        }, () -> {
            LOGGER.info("This dirty subscription has completed.");
        });
        this.compDisp.add(disp);

    }

    @Override
    public DockKey getDockKey() {
        return DockKeys.DOCKKEY_DMX_SCENERY_VIEW;
    }

    @Override
    public Component getComponent() {
        return sceneryPanel;
    }

    public void cleanup() {
        if (this.sceneryTreePanel != null) {
            this.sceneryTreePanel.cleanup();
        }

        // dispose the has pending changes subscription
        this.compDisp.dispose();

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy