/**
* Send speed override commands to the backend.
*/
/*
Copyright 2016-2017 Will Winder
This file is part of Universal Gcode Sender (UGS).
UGS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
UGS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with UGS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.willwinder.universalgcodesender.uielements.panels;
import com.willwinder.universalgcodesender.i18n.Localization;
import com.willwinder.universalgcodesender.listeners.ControllerListener;
import com.willwinder.universalgcodesender.listeners.ControllerStatus;
import com.willwinder.universalgcodesender.listeners.ControllerStatus.AccessoryStates;
import com.willwinder.universalgcodesender.listeners.UGSEventListener;
import com.willwinder.universalgcodesender.model.BackendAPI;
import com.willwinder.universalgcodesender.model.Overrides;
import com.willwinder.universalgcodesender.model.Position;
import static com.willwinder.universalgcodesender.model.UGSEvent.ControlState.COMM_DISCONNECTED;
import com.willwinder.universalgcodesender.types.GcodeCommand;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.UIManager;
import net.miginfocom.swing.MigLayout;
/**
*
* @author wwinder
*/
public final class OverridesPanel extends JPanel implements UGSEventListener, ControllerListener {
private final BackendAPI backend;
private final ArrayList<Component> components = new ArrayList<>();
private final JLabel feedSpeed = new JLabel("100%");
private final JRadioButton feedRadio = new JRadioButton(FEED_SHORT);
private final JLabel spindleSpeed = new JLabel("100%");
private final JRadioButton spindleRadio = new JRadioButton(SPINDLE_SHORT);
private final JLabel rapidSpeed = new JLabel("100%");
private final JRadioButton rapidRadio = new JRadioButton(RAPID_SHORT);
private final JButton adjust1 = new JButton("");
private final JButton adjust2 = new JButton("");
private final JButton adjust3 = new JButton("");
private final JButton adjust4 = new JButton("");
private final JButton adjust5 = new JButton("");
private final JButton toggleSpindle = new JButton(SPINDLE_SHORT);
private final JButton toggleFloodCoolant = new JButton(FLOOD);
private final JButton toggleMistCoolant = new JButton(MIST);
private final ArrayList<RealTimeAction> rapidActions = new ArrayList<>();
private final ArrayList<RealTimeAction> spindleActions = new ArrayList<>();
private final ArrayList<RealTimeAction> feedActions = new ArrayList<>();
public final static String FEED_SHORT = Localization.getString("overrides.feed.short");
public final static String SPINDLE_SHORT = Localization.getString("overrides.spindle.short");
public final static String RAPID_SHORT = Localization.getString("overrides.rapid.short");
public final static String TOGGLE_SHORT = Localization.getString("overrides.toggle.short");
public final static String RESET_SPINDLE = Localization.getString("overrides.spindle.reset");
public final static String RESET_FEED = Localization.getString("overrides.feed.reset");
public final static String MINUS_COARSE = "--";
public final static String MINUS_FINE = "-";
public final static String PLUS_COARSE = "++";
public final static String PLUS_FINE = "+";
public final static String RAPID_LOW = Localization.getString("overrides.rapid.low");
public final static String RAPID_MEDIUM = Localization.getString("overrides.rapid.medium");
public final static String RAPID_FULL = Localization.getString("overrides.rapid.full");
public final static String MIST = Localization.getString("overrides.mist");
public final static String FLOOD = Localization.getString("overrides.flood");
public OverridesPanel(BackendAPI backend) {
this.backend = backend;
if (backend != null) {
backend.addUGSEventListener(this);
backend.addControllerListener(this);
}
initComponents();
updateControls();
}
public void updateControls() {
boolean enabled = backend.getControlState() != COMM_DISCONNECTED;
this.setEnabled(enabled);
for (Component c : components) {
c.setEnabled(enabled);
}
if (enabled) {
radioSelected();
}
}
@Override
public void UGSEvent(com.willwinder.universalgcodesender.model.UGSEvent evt) {
if (evt.isStateChangeEvent()) {
updateControls();
}
}
public void add(Component comp, String str) {
super.add(comp, str);
if (comp instanceof JButton || comp instanceof JRadioButton)
components.add(comp);
}
public Component add(Component comp) {
Component ret = super.add(comp);
if (comp instanceof JButton || comp instanceof JRadioButton)
components.add(comp);
return ret;
}
private void radioSelected() {
if (rapidRadio.isSelected()) {
adjust2.setEnabled(false);
adjust5.setEnabled(false);
adjust1.setText(RAPID_LOW);
adjust2.setText("");
adjust3.setText(RAPID_MEDIUM);
adjust4.setText(RAPID_FULL);
adjust5.setText("");
adjust1.setAction(rapidActions.get(0));
adjust3.setAction(rapidActions.get(1));
adjust4.setAction(rapidActions.get(2));
} else {
adjust2.setEnabled(true);
adjust5.setEnabled(true);
adjust1.setText(MINUS_COARSE);
adjust2.setText(MINUS_FINE);
adjust4.setText(PLUS_FINE);
adjust5.setText(PLUS_COARSE);
ArrayList<RealTimeAction> actions = null;
if (feedRadio.isSelected()) {
adjust3.setText(RESET_FEED);
actions = feedActions;
} else if (spindleRadio.isSelected()) {
adjust3.setText(RESET_SPINDLE);
actions = spindleActions;
}
if (actions != null) {
adjust1.setAction(actions.get(0));
adjust2.setAction(actions.get(1));
adjust3.setAction(actions.get(2));
adjust4.setAction(actions.get(3));
adjust5.setAction(actions.get(4));
}
}
}
private void initComponents() {
rapidActions.add(new RealTimeAction(RAPID_LOW, Overrides.CMD_RAPID_OVR_LOW, backend));
rapidActions.add(new RealTimeAction(RAPID_MEDIUM, Overrides.CMD_RAPID_OVR_MEDIUM, backend));
rapidActions.add(new RealTimeAction(RAPID_FULL, Overrides.CMD_RAPID_OVR_RESET, backend));
spindleActions.add(new RealTimeAction(MINUS_COARSE, Overrides.CMD_SPINDLE_OVR_COARSE_MINUS, backend));
spindleActions.add(new RealTimeAction(MINUS_FINE, Overrides.CMD_SPINDLE_OVR_FINE_MINUS, backend));
spindleActions.add(new RealTimeAction(RESET_SPINDLE, Overrides.CMD_SPINDLE_OVR_RESET, backend));
spindleActions.add(new RealTimeAction(PLUS_FINE, Overrides.CMD_SPINDLE_OVR_FINE_PLUS, backend));
spindleActions.add(new RealTimeAction(PLUS_COARSE, Overrides.CMD_SPINDLE_OVR_COARSE_PLUS, backend));
feedActions.add(new RealTimeAction(MINUS_COARSE, Overrides.CMD_FEED_OVR_COARSE_MINUS, backend));
feedActions.add(new RealTimeAction(MINUS_FINE, Overrides.CMD_FEED_OVR_FINE_MINUS, backend));
feedActions.add(new RealTimeAction(RESET_FEED, Overrides.CMD_FEED_OVR_RESET, backend));
feedActions.add(new RealTimeAction(PLUS_FINE, Overrides.CMD_FEED_OVR_FINE_PLUS, backend));
feedActions.add(new RealTimeAction(PLUS_COARSE, Overrides.CMD_FEED_OVR_COARSE_PLUS, backend));
adjust1.setEnabled(false);
adjust2.setEnabled(false);
adjust3.setEnabled(false);
adjust4.setEnabled(false);
adjust5.setEnabled(false);
ButtonGroup group = new ButtonGroup();
group.add(feedRadio);
group.add(spindleRadio);
group.add(rapidRadio);
// Initialize callbacks
// Radio buttons
feedRadio.addActionListener((ActionEvent ae) -> radioSelected());
spindleRadio.addActionListener((ActionEvent ae) -> radioSelected());
rapidRadio.addActionListener((ActionEvent ae) -> radioSelected());
// Toggle actions
toggleSpindle.setAction(new RealTimeAction("spindle", Overrides.CMD_TOGGLE_SPINDLE, backend));
toggleSpindle.setBackground(Color.RED);
toggleFloodCoolant.setAction(new RealTimeAction("flood", Overrides.CMD_TOGGLE_FLOOD_COOLANT, backend));
toggleFloodCoolant.setBackground(Color.RED);
toggleMistCoolant.setAction(new RealTimeAction("mist", Overrides.CMD_TOGGLE_MIST_COOLANT, backend));
toggleMistCoolant.setBackground(Color.RED);
// Layout components
this.setLayout(new MigLayout("wrap 4"));
this.add(feedRadio);
this.add(spindleRadio);
this.add(rapidRadio, "wrap");
this.add(new JLabel(FEED_SHORT + ":"));
this.add(feedSpeed);
this.add(adjust1);
this.add(adjust2);
this.add(new JLabel(SPINDLE_SHORT + ":"));
this.add(spindleSpeed);
this.add(adjust3, "span 2");
this.add(new JLabel("Rapid:"));
this.add(rapidSpeed);
this.add(adjust4);
this.add(adjust5, "wrap");
this.add(new JLabel(TOGGLE_SHORT + ":"));
this.add(toggleSpindle);
this.add(toggleFloodCoolant);
this.add(toggleMistCoolant);
}
@Override
public void controlStateChange(com.willwinder.universalgcodesender.model.UGSEvent.ControlState state) {
}
@Override
public void fileStreamComplete(String filename, boolean success) {
}
@Override
public void commandSkipped(GcodeCommand command) {
}
@Override
public void commandSent(GcodeCommand command) {
}
@Override
public void commandComplete(GcodeCommand command) {
}
@Override
public void commandComment(String comment) {
}
@Override
public void probeCoordinates(Position p) {
}
@Override
public void messageForConsole(MessageType type, String msg) {
}
@Override
public void statusStringListener(ControllerStatus status) {
if (status.getOverrides() != null) {
this.feedSpeed.setText(status.getOverrides().feed + "%");
this.spindleSpeed.setText(status.getOverrides().spindle + "%");
this.rapidSpeed.setText(status.getOverrides().rapid + "%");
}
if (status.getAccessoryStates() != null) {
Color defaultBackground = UIManager.getColor("Panel.background");
AccessoryStates states = status.getAccessoryStates();
toggleSpindle.setBackground((states.SpindleCW || states.SpindleCCW) ? Color.GREEN : Color.RED);
toggleFloodCoolant.setBackground(states.Flood ? Color.GREEN : Color.RED);
toggleMistCoolant.setBackground(states.Mist ? Color.GREEN : Color.RED);
toggleSpindle.setOpaque(true);
toggleFloodCoolant.setOpaque(true);
toggleMistCoolant.setOpaque(true);
}
}
@Override
public void postProcessData(int numRows) {
}
private static class RealTimeAction extends AbstractAction {
private final Overrides command;
private final BackendAPI backend;
public RealTimeAction(String name, Overrides override, BackendAPI backend) {
this.putValue(Action.NAME, name);
this.command = override;
this.backend = backend;
}
@Override
public void actionPerformed(ActionEvent e) {
if (isEnabled()) {
try {
backend.sendOverrideCommand(command);
} catch (Exception ex) {
Logger.getLogger(OverridesPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}