com.maccasoft.composer.CommandControl.java Source code

Java tutorial

Introduction

Here is the source code for com.maccasoft.composer.CommandControl.java

Source

/*
 * Copyright (c) 2016 Marco Maccaferri and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Marco Maccaferri - initial API and implementation
 */

package com.maccasoft.composer;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Text;

import com.maccasoft.composer.internal.HexStringToLongConverter;
import com.maccasoft.composer.internal.NumberToHexStringConverter;
import com.maccasoft.composer.internal.NumberToStringConverter;
import com.maccasoft.composer.internal.StringToDoubleConverter;
import com.maccasoft.composer.model.Command;

public class CommandControl {

    Composite container;

    Button disable;
    Spinner repeat;
    Combo action;

    Composite stackContainer;
    StackLayout stackLayout;

    Combo property;
    Composite propertiesStackContainer;
    StackLayout propertiesStackLayout;

    Text frequency;
    Text frequencyNote;
    Text frequencyRegister;
    Text duration;
    Text reset;
    Text envelopeRegister;
    Text volume;
    Text volumeRegister;
    Text variable;
    Text fixed;
    Text modulationRegister;
    Spinner steps;

    private FontMetrics fontMetrics;

    final FocusAdapter textFocusListener = new FocusAdapter() {

        @Override
        public void focusGained(FocusEvent e) {
            ((Text) e.widget).selectAll();
        }

        @Override
        public void focusLost(FocusEvent e) {
            ((Text) e.widget).clearSelection();
        }
    };

    public CommandControl(Composite parent) {
        container = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(6, false);
        layout.marginWidth = layout.marginHeight = 0;
        container.setLayout(layout);

        GC gc = new GC(container);
        fontMetrics = gc.getFontMetrics();
        gc.dispose();

        disable = new Button(container, SWT.CHECK);
        disable.setToolTipText("Check to disable entry");
        disable.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                updateEnablement();
            }
        });

        repeat = new Spinner(container, SWT.BORDER);
        repeat.setValues(0, 0, 99999, 0, 1, 1);
        repeat.setToolTipText("Repeat count (ms)");
        repeat.setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 5), SWT.DEFAULT));

        Label label = new Label(container, SWT.NONE);
        label.setText("x");

        action = new Combo(container, SWT.DROP_DOWN | SWT.READ_ONLY);
        action.setItems(new String[] { "JUMP", "SET", "MODIFY" });
        action.setToolTipText("Command");
        action.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                updateVisibleStack();
            }
        });

        createStack(container);
    }

    void updateEnablement() {
        boolean enabled = !disable.getSelection();
        repeat.setEnabled(enabled);
        action.setEnabled(enabled);
        property.setEnabled(enabled);
        frequency.setEnabled(enabled);
        frequencyNote.setEnabled(enabled);
        frequencyRegister.setEnabled(enabled);
        duration.setEnabled(enabled);
        reset.setEnabled(enabled);
        envelopeRegister.setEnabled(enabled);
        volume.setEnabled(enabled);
        volumeRegister.setEnabled(enabled);
        variable.setEnabled(enabled);
        fixed.setEnabled(enabled);
        modulationRegister.setEnabled(enabled);
        steps.setEnabled(enabled);
    }

    void updateVisibleStack() {
        Control[] childs = stackContainer.getChildren();

        int selection = action.getSelectionIndex();
        if (selection >= childs.length) {
            selection = childs.length - 1;
        }

        stackLayout.topControl = childs[selection];
        stackContainer.layout();
    }

    void createStack(Composite parent) {
        stackContainer = new Composite(parent, SWT.NONE);
        stackLayout = new StackLayout();
        stackLayout.marginWidth = stackLayout.marginHeight = 0;
        stackContainer.setLayout(stackLayout);
        stackContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        createJumpControls(stackContainer);

        Composite container = new Composite(stackContainer, SWT.NONE);
        GridLayout layout = new GridLayout(2, false);
        layout.marginWidth = layout.marginHeight = 0;
        container.setLayout(layout);

        property = new Combo(container, SWT.DROP_DOWN | SWT.READ_ONLY);
        property.setToolTipText("Property");
        property.setItems(new String[] { "FREQUENCY", "FREQUENCY_NOTE", "ENVELOPE", "VOLUME", "MODULATION",
                "FREQUENCY_REGISTER", "ENVELOPE_REGISTER", "VOLUME_REGISTER", "MODULATION_REGISTER", });
        property.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                updateVisibleProperty();
            }
        });

        propertiesStackContainer = new Composite(container, SWT.NONE);
        propertiesStackLayout = new StackLayout();
        propertiesStackLayout.marginWidth = propertiesStackLayout.marginHeight = 0;
        propertiesStackContainer.setLayout(propertiesStackLayout);
        propertiesStackContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        createFrequencyControls(propertiesStackContainer);
        createFrequencyNoteControls(propertiesStackContainer);
        createEnvelopeControls(propertiesStackContainer);
        createVolumeControls(propertiesStackContainer);
        createModulationControls(propertiesStackContainer);

        createFrequencyRegisterControls(propertiesStackContainer);
        createEnvelopeRegisterControls(propertiesStackContainer);
        createVolumeRegisterControls(propertiesStackContainer);
        createModulationRegisterControls(propertiesStackContainer);
    }

    void updateVisibleProperty() {
        Control[] childs = propertiesStackContainer.getChildren();
        if (property.getSelectionIndex() != -1) {
            propertiesStackLayout.topControl = childs[property.getSelectionIndex()];
        } else {
            propertiesStackLayout.topControl = childs[childs.length - 1];
        }
        propertiesStackContainer.layout();
    }

    void createFrequencyControls(Composite parent) {
        Composite container = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(2, false);
        layout.marginWidth = layout.marginHeight = 0;
        container.setLayout(layout);

        frequency = new Text(container, SWT.BORDER | SWT.CENTER);
        frequency.setToolTipText("Frequency");
        frequency.setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 11), SWT.DEFAULT));
        frequency.addFocusListener(textFocusListener);

        Label label = new Label(container, SWT.NONE);
        label.setText("Hz");
    }

    void createFrequencyNoteControls(Composite parent) {
        Composite container = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(1, false);
        layout.marginWidth = layout.marginHeight = 0;
        container.setLayout(layout);

        frequencyNote = new Text(container, SWT.BORDER | SWT.CENTER);
        frequencyNote.setToolTipText("Note");
        frequencyNote.setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 11), SWT.DEFAULT));
        frequencyNote.addFocusListener(textFocusListener);
    }

    void createFrequencyRegisterControls(Composite parent) {
        Composite container = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(1, false);
        layout.marginWidth = layout.marginHeight = 0;
        container.setLayout(layout);

        frequencyRegister = new Text(container, SWT.BORDER | SWT.CENTER);
        frequencyRegister.setToolTipText("Register value (hex)");
        frequencyRegister
                .setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 11), SWT.DEFAULT));
        frequencyRegister.addFocusListener(textFocusListener);
    }

    void createEnvelopeControls(Composite parent) {
        Composite container = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(4, false);
        layout.marginWidth = layout.marginHeight = 0;
        container.setLayout(layout);

        duration = new Text(container, SWT.BORDER | SWT.CENTER);
        duration.setToolTipText("Duration");
        duration.setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 11), SWT.DEFAULT));
        duration.addFocusListener(textFocusListener);

        Label label = new Label(container, SWT.NONE);
        label.setText("ms.");
        label.setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 3), SWT.DEFAULT));

        reset = new Text(container, SWT.BORDER | SWT.CENTER);
        reset.setToolTipText("Reset amplitude");
        reset.setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 6), SWT.DEFAULT));
        reset.addFocusListener(textFocusListener);

        label = new Label(container, SWT.NONE);
        label.setText("%");
    }

    void createEnvelopeRegisterControls(Composite parent) {
        Composite container = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(1, false);
        layout.marginWidth = layout.marginHeight = 0;
        container.setLayout(layout);

        envelopeRegister = new Text(container, SWT.BORDER | SWT.CENTER);
        envelopeRegister.setToolTipText("Register value (hex)");
        envelopeRegister
                .setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 11), SWT.DEFAULT));
        envelopeRegister.addFocusListener(textFocusListener);
    }

    void createVolumeControls(Composite parent) {
        Composite container = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(2, false);
        layout.marginWidth = layout.marginHeight = 0;
        container.setLayout(layout);

        volume = new Text(container, SWT.BORDER | SWT.CENTER);
        volume.setToolTipText("Max. volume level");
        volume.setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 11), SWT.DEFAULT));
        volume.addFocusListener(textFocusListener);

        Label label = new Label(container, SWT.NONE);
        label.setText("%");
    }

    void createVolumeRegisterControls(Composite parent) {
        Composite container = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(1, false);
        layout.marginWidth = layout.marginHeight = 0;
        container.setLayout(layout);

        volumeRegister = new Text(container, SWT.BORDER | SWT.CENTER);
        volumeRegister.setToolTipText("Register value (hex)");
        volumeRegister
                .setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 11), SWT.DEFAULT));
        volumeRegister.addFocusListener(textFocusListener);
    }

    void createModulationControls(Composite parent) {
        Composite container = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(4, false);
        layout.marginWidth = layout.marginHeight = 0;
        container.setLayout(layout);

        variable = new Text(container, SWT.BORDER | SWT.CENTER);
        variable.setToolTipText("Variable modulation");
        variable.setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 11), SWT.DEFAULT));
        variable.addFocusListener(textFocusListener);

        Label label = new Label(container, SWT.NONE);
        label.setText("Hz");
        label.setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 3), SWT.DEFAULT));

        fixed = new Text(container, SWT.BORDER | SWT.CENTER);
        fixed.setToolTipText("Fixed duty cycle");
        fixed.setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 6), SWT.DEFAULT));
        fixed.addFocusListener(textFocusListener);

        label = new Label(container, SWT.NONE);
        label.setText("%");
    }

    void createModulationRegisterControls(Composite parent) {
        Composite container = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(1, false);
        layout.marginWidth = layout.marginHeight = 0;
        container.setLayout(layout);

        modulationRegister = new Text(container, SWT.BORDER | SWT.CENTER);
        modulationRegister.setToolTipText("Register value (hex)");
        modulationRegister
                .setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 11), SWT.DEFAULT));
        modulationRegister.addFocusListener(textFocusListener);
    }

    void createJumpControls(Composite parent) {
        Composite container = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(1, false);
        layout.marginWidth = layout.marginHeight = 0;
        container.setLayout(layout);

        steps = new Spinner(container, SWT.BORDER);
        steps.setValues(0, -9999, 9999, 0, 1, 1);
        steps.setToolTipText("Number of instructions");
        steps.setLayoutData(new GridData(Dialog.convertWidthInCharsToPixels(fontMetrics, 5), SWT.DEFAULT));
    }

    public void bind(DataBindingContext ctx, Command cmd) {
        List<Binding> bindings = new ArrayList<Binding>();

        bindings.add(ctx.bindValue(WidgetProperties.selection().observe(disable),
                BeanProperties.value(cmd.getClass(), Command.PROP_DISABLED).observe(cmd)));

        bindings.add(ctx.bindValue(WidgetProperties.selection().observe(repeat),
                BeanProperties.value(cmd.getClass(), Command.PROP_REPEAT).observe(cmd)));
        bindings.add(ctx.bindValue(WidgetProperties.singleSelectionIndex().observe(action),
                BeanProperties.value(cmd.getClass(), Command.PROP_ACTION).observe(cmd)));
        bindings.add(ctx.bindValue(WidgetProperties.singleSelectionIndex().observe(property),
                BeanProperties.value(cmd.getClass(), Command.PROP_PROPERTY).observe(cmd)));

        bindings.add(ctx.bindValue(WidgetProperties.selection().observe(steps),
                BeanProperties.value(cmd.getClass(), Command.PROP_VALUE).observe(cmd)));

        bindings.add(ctx.bindValue(WidgetProperties.text(SWT.Modify).observe(frequency),
                BeanProperties.value(cmd.getClass(), Command.PROP_FREQUENCY).observe(cmd),
                new UpdateValueStrategy().setConverter(new StringToDoubleConverter()),
                new UpdateValueStrategy().setConverter(new NumberToStringConverter())));
        bindings.add(ctx.bindValue(WidgetProperties.text(SWT.Modify).observe(frequencyNote),
                BeanProperties.value(cmd.getClass(), Command.PROP_FREQUENCY_NOTE).observe(cmd)));

        bindings.add(ctx.bindValue(WidgetProperties.text(SWT.Modify).observe(duration),
                BeanProperties.value(cmd.getClass(), Command.PROP_ENVELOPE_LENGTH).observe(cmd),
                new UpdateValueStrategy().setConverter(new StringToDoubleConverter()),
                new UpdateValueStrategy().setConverter(new NumberToStringConverter())));
        bindings.add(ctx.bindValue(WidgetProperties.text(SWT.Modify).observe(reset),
                BeanProperties.value(cmd.getClass(), Command.PROP_ENVELOPE_RESET).observe(cmd),
                new UpdateValueStrategy().setConverter(new StringToDoubleConverter()),
                new UpdateValueStrategy().setConverter(new NumberToStringConverter())));

        bindings.add(ctx.bindValue(WidgetProperties.text(SWT.Modify).observe(volume),
                BeanProperties.value(cmd.getClass(), Command.PROP_VOLUME).observe(cmd),
                new UpdateValueStrategy().setConverter(new StringToDoubleConverter()),
                new UpdateValueStrategy().setConverter(new NumberToStringConverter())));

        bindings.add(ctx.bindValue(WidgetProperties.text(SWT.Modify).observe(variable),
                BeanProperties.value(cmd.getClass(), Command.PROP_MODULATION).observe(cmd),
                new UpdateValueStrategy().setConverter(new StringToDoubleConverter()),
                new UpdateValueStrategy().setConverter(new NumberToStringConverter())));
        bindings.add(ctx.bindValue(WidgetProperties.text(SWT.Modify).observe(fixed),
                BeanProperties.value(cmd.getClass(), Command.PROP_DUTY_CYCLE).observe(cmd),
                new UpdateValueStrategy().setConverter(new StringToDoubleConverter()),
                new UpdateValueStrategy().setConverter(new NumberToStringConverter())));

        bindings.add(ctx.bindValue(WidgetProperties.text(SWT.Modify).observe(frequencyRegister),
                BeanProperties.value(cmd.getClass(), Command.PROP_FREQUENCY_REGISTER).observe(cmd),
                new UpdateValueStrategy().setConverter(new HexStringToLongConverter()),
                new UpdateValueStrategy().setConverter(new NumberToHexStringConverter())));
        bindings.add(ctx.bindValue(WidgetProperties.text(SWT.Modify).observe(envelopeRegister),
                BeanProperties.value(cmd.getClass(), Command.PROP_ENVELOPE_REGISTER).observe(cmd),
                new UpdateValueStrategy().setConverter(new HexStringToLongConverter()),
                new UpdateValueStrategy().setConverter(new NumberToHexStringConverter())));
        bindings.add(ctx.bindValue(WidgetProperties.text(SWT.Modify).observe(volumeRegister),
                BeanProperties.value(cmd.getClass(), Command.PROP_VOLUME_REGISTER).observe(cmd),
                new UpdateValueStrategy().setConverter(new HexStringToLongConverter()),
                new UpdateValueStrategy().setConverter(new NumberToHexStringConverter())));
        bindings.add(ctx.bindValue(WidgetProperties.text(SWT.Modify).observe(modulationRegister),
                BeanProperties.value(cmd.getClass(), Command.PROP_MODULATION_REGISTER).observe(cmd),
                new UpdateValueStrategy().setConverter(new HexStringToLongConverter()),
                new UpdateValueStrategy().setConverter(new NumberToHexStringConverter())));

        for (Iterator<Binding> it = bindings.iterator(); it.hasNext();) {
            it.next().updateModelToTarget();
        }

        updateVisibleStack();
        updateVisibleProperty();
        updateEnablement();
    }

    public Control getControl() {
        return container;
    }

    public void setLayoutData(Object layoutData) {
        container.setLayoutData(layoutData);
    }

    public Object getLayoutData() {
        return container.getLayoutData();
    }
}