/** * 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); } } } } }