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

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

There is a newer version: 2.0.29
Show 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 java.util.function.Supplier;

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

import org.bidib.wizard.api.locale.Resources;
import org.bidib.wizard.api.model.NodeProvider;
import org.bidib.wizard.client.common.view.DockKeys;
import org.bidib.wizard.client.common.view.listener.TabStatusListener;
import org.bidib.wizard.common.utils.ImageUtils;
import org.bidib.wizard.dmx.client.controller.listener.DmxModelerControllerListener;
import org.bidib.wizard.dmx.client.model.DmxDimmerConfigModel;
import org.bidib.wizard.dmx.client.model.DmxSceneryModel;
import org.bidib.wizard.dmx.client.view.panel.DmxDimmerConfigTableView;
import org.bidib.wizard.dmx.client.view.panel.DmxModelerChartView;
import org.bidib.wizard.model.dmx.DmxDimmer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jidesoft.swing.JideTabbedPane;
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;

/**
 * The {@code DmxDimmerConfigView} is the view that shows the table and the chart with the DMX channel values for the
 * dimmer.
 */
public class DmxDimmerConfigView implements Dockable {

    private static final Logger LOGGER = LoggerFactory.getLogger(DmxDimmerConfigView.class);

    private final DockKey DOCKKEY = new DockKey(DockKeys.DMX_DIMMER_CONFIG_VIEW);

    private final DmxModelerControllerListener controllerListener;

    private DmxDimmerConfigTableView dmxDimmerConfigTableView;

    private DmxModelerChartView dmxModelerChartView;

    private final DockableStateChangeListener dockableStateChangeListener;

    private final Supplier nodeProviderSupplier;

    private final JideTabbedPane tabbedPane;

    private final AtomicBoolean focusListenerAdded = new AtomicBoolean();

    private final DmxToolBarProvider dmxToolbarProvider;

    public DmxDimmerConfigView(final DockingDesktop desktop, final DmxModelerControllerListener controllerListener,
        final DmxDimmer dmxDimmer, final DmxSceneryModel dmxSceneryModel,
        final Supplier nodeProviderSupplier, final DmxToolBarProvider dmxToolbarProvider) {

        this.controllerListener = controllerListener;
        this.nodeProviderSupplier = nodeProviderSupplier;
        this.dmxToolbarProvider = dmxToolbarProvider;

        DOCKKEY.setName(prepareTitle(dmxDimmer));
        // turn off autohide and enable close and float-enabled features
        DOCKKEY.setCloseEnabled(true);
        DOCKKEY.setAutoHideEnabled(false);
        DOCKKEY.setFloatEnabled(true);

        DOCKKEY.setKey(prepareKey(dmxDimmer));
        LOGGER.info("Created new DOCKKEY: {}", DOCKKEY.getKey());

        final FocusListener focusListener = new FocusListener() {

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

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

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

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

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

                DOCKKEY.setIcon(icon);
            }
        };

        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(DmxDimmerConfigView.this) && newState.isClosed()) {
                    LOGGER.info("The DmxDimmerConfigView is closed.");
                    // we are closed
                    desktop.removeDockableStateChangeListener(dockableStateChangeListener);

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

                    DmxDimmerConfigView.this.dmxToolbarProvider.removeView(dockable);

                    if (dmxDimmerConfigTableView != null) {
                        dmxDimmerConfigTableView.cleanup();
                    }
                }

            }
        };
        desktop.addDockableStateChangeListener(dockableStateChangeListener);

        this.tabbedPane = new JideTabbedPane();

        final DmxDimmerConfigModel dmxDimmerConfigModel = new DmxDimmerConfigModel(dmxDimmer, dmxSceneryModel);

        // create the table view
        this.dmxDimmerConfigTableView = new DmxDimmerConfigTableView(dmxDimmerConfigModel, this.controllerListener);
        this.dmxDimmerConfigTableView.initComponents();

        this.dmxDimmerConfigTableView.prepareModel();

        // create the chart view
        this.dmxModelerChartView = new DmxModelerChartView(dmxDimmerConfigModel);
        this.dmxModelerChartView.initComponents();
        // load the scenery points
        this.dmxModelerChartView.loadSceneryPoints();

        this.tabbedPane.add(this.dmxDimmerConfigTableView.getComponent());
        this.tabbedPane.add(this.dmxModelerChartView.getComponent());

        this.dmxDimmerConfigTableView.addTableModelListener(obj -> {
            LOGGER.info("Refresh the chart data.");

            this.dmxModelerChartView.refreshChartData();

            // get the real dirty state
            boolean isDirty = this.dmxDimmerConfigTableView.hasPendingChanges();
            tabStatusListener.updatePendingChanges(dmxModelerChartView.getComponent(), isDirty);

            // enable the write CV values toolbar button
            boolean hasPendingChanges = this.dmxToolbarProvider.setPendingChanges(DmxDimmerConfigView.this, isDirty);
            if (hasPendingChanges) {
                // set the pending changes flag in the scenery model to enable the toolbar button in the scenery view
                this.controllerListener.setPendingChanges(hasPendingChanges);
            }
        });

        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 (DmxDimmerConfigView.this.equals(selectedDockable)) {
                    LOGGER.info("The DmxDimmerConfigView is selected.");

                    dmxToolbarProvider.setVisible(DmxDimmerConfigView.this, true);
                }
                else {
                    LOGGER.info("The DmxDimmerConfigView is not selected.");
                    // if (toolbarCvDefinition.isVisible()) {
                    dmxToolbarProvider.setVisible(DmxDimmerConfigView.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 = DmxDimmerConfigView.this;
                        DockTabbedPane dockTabbedPane =
                            (DockTabbedPane) DockingUtilities.findTabbedDockableContainer(dockable);
                        if (dockTabbedPane != null) {
                            dockTabbedPane.addFocusListener(focusListener);

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

        dmxToolbarProvider.setVisible(this, true);
    }

    /**
     * Prepare the key for the current DMX dimmer.
     * 
     * @param dmxDimmer
     *            the dmx dimmer
     * @return the dockable key
     */
    public static String prepareKey(final DmxDimmer dmxDimmer) {
        return DmxDimmerConfigView.class.getSimpleName() + " - " + dmxDimmer.getId();
    }

    /**
     * Prepare the frame title for the current DMX dimmer.
     * 
     * @param dmxDimmer
     *            the dmx dimmer
     * @return the frame title
     */
    public static String prepareTitle(final DmxDimmer dmxDimmer) {
        return Resources.getString(DmxDimmerConfigView.class, "title") + " - " + dmxDimmer.getName();
    }

    @Override
    public DockKey getDockKey() {
        return DOCKKEY;
    }

    @Override
    public Component getComponent() {
        return this.tabbedPane;
    }

    public void selectedDmxChannelChanged(DmxDimmer dmxDimmer, int dmxChannelId) {

        this.dmxModelerChartView.selectedDmxChannelChanged(dmxDimmer, dmxChannelId);
    }

    public boolean hasPendingChanges() {
        return this.dmxDimmerConfigTableView.hasPendingChanges();
    }

    public void writeChangedCvValues() {
        LOGGER.info("Write changed CV values to node.");

        // write the changed CV values to the node
        this.dmxDimmerConfigTableView.writeChangedCvValues();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy