001package jmri.jmrit.logix;
002
003import java.awt.Dimension;
004import java.awt.event.ActionEvent;
005import java.awt.event.WindowAdapter;
006import java.awt.event.WindowEvent;
007
008import javax.swing.ButtonGroup;
009import javax.swing.JDesktopPane;
010import javax.swing.JMenu;
011import javax.swing.JMenuBar;
012import javax.swing.JMenuItem;
013import javax.swing.JRadioButtonMenuItem;
014
015import jmri.DccThrottle;
016import jmri.InstanceManager;
017import jmri.JmriException;
018import jmri.PowerManager;
019import jmri.SpeedStepMode;
020import jmri.jmrit.throttle.implementation.ThrottleJInternalFrameSubControl;
021import jmri.jmrit.throttle.panels.FunctionButton;
022import jmri.util.JmriJFrame;
023
024/**
025 * A JFrame to contain throttle elements such as speed control, function panel.
026 * It keeps a record of the throttle commands for playback later.
027 * <p>
028 *
029 * Modeled on package jmri.jmrit.throttle by
030 *
031 * @author Glen Oberhauser
032 * @author Bob Jacobsen Copyright 2008
033 *
034 * @author Pete Cressman Copyright 2009, 2020
035 */
036public class LearnThrottleFrame extends JmriJFrame {
037
038    private final WarrantFrame _warrantFrame;
039    private PowerManager powerMgr = null;
040    private LearnControlPanel _controlPanel;
041    private LearnFunctionPanel _functionPanel;
042    private LearnSpeedPanel _speedPanel;
043    private ThrottleJInternalFrameSubControl _controlPanelJIF;
044    private ThrottleJInternalFrameSubControl _functionPanelJIF;
045
046    /**
047     * Default constructor
048     * @param warrantFrame caller
049     */
050    public LearnThrottleFrame(WarrantFrame warrantFrame) {
051        super(false, false);
052        _warrantFrame = warrantFrame;
053        powerMgr = InstanceManager.getNullableDefault(jmri.PowerManager.class);
054        if (powerMgr == null) {
055            log.info("No power manager instance found, panel not active");
056        }
057        initGUI();
058        setVisible(true);
059    }
060
061    /**
062     * Get notification that a throttle has been found as you requested.
063     *
064     * @param t An instantiation of the DccThrottle with the address requested.
065     */
066    public void notifyThrottleFound(DccThrottle t) {
067        if (log.isDebugEnabled()) {
068            log.debug("notifyThrottleFound address= {} class= {}",t.getLocoAddress(),t.getClass().getName());
069        }
070        _controlPanel.notifyAddressThrottleFound(t);
071        _functionPanel.notifyAddressThrottleFound(t);
072        _speedPanel.notifyAddressThrottleFound(t);
073        setSpeedSetting(0.0f);      // be sure loco is stopped.
074        setButtonForward(t.getIsForward());
075        String name = _warrantFrame.getTrainName();
076        if (name == null || name.isEmpty()) {
077            jmri.jmrit.roster.RosterEntry re = _warrantFrame._speedUtil.getRosterEntry();
078            if (re != null) {
079                name = re.getId();
080            } else {
081                name = t.getLocoAddress().toString();
082            }
083        } else {
084            name =name +" - " + t.getLocoAddress().toString();
085        }
086        setTitle(name);
087    }
088
089    private void initGUI() {
090        setTitle(Bundle.getMessage("ThrottleTitle"));
091        this.addWindowListener(new WindowAdapter() {
092            @Override
093            public void windowClosing(WindowEvent e) {
094                _warrantFrame.close();
095                dispose();
096            }
097        });
098        initializeMenu();
099
100        _controlPanel = new LearnControlPanel(this);
101        _controlPanel.setVisible(true);
102        _controlPanel.setEnabled(false);
103        _controlPanelJIF = new ThrottleJInternalFrameSubControl(Bundle.getMessage("speed"), _controlPanel, true);
104        _controlPanelJIF.setSize(_controlPanel.getPreferredSize());
105
106        int width = 3 * (FunctionButton.getButtonWidth()) + 2 * 3 * 5 + 11;   // = 192
107        int height = 9 * (FunctionButton.getButtonHeight()) + 2 * 6 * 5 + 20; // FunctionButton.BUT_IMG_SIZE = 45
108        _functionPanel = new LearnFunctionPanel(this);        
109        _functionPanel.setVisible(true);
110        _functionPanel.setEnabled(false);
111        _functionPanelJIF = new ThrottleJInternalFrameSubControl(Bundle.getMessage("setFunction"), _functionPanel, true);
112        _functionPanelJIF.setSize(width, height);
113
114        _speedPanel = new LearnSpeedPanel(_warrantFrame.getWarrant());
115        _speedPanel.setSize(_functionPanelJIF.getWidth(), _controlPanelJIF.getHeight() - _functionPanelJIF.getHeight());
116        _speedPanel.setVisible(true);
117        _speedPanel.setClosable(true);
118        _speedPanel.setTitle(java.util.ResourceBundle.getBundle("jmri/jmrit/throttle/ThrottleBundle").getString("ThrottleMenuViewSpeedPanel"));
119
120        _controlPanelJIF.setLocation(0, 0);
121        _functionPanelJIF.setLocation(_controlPanel.getWidth(), 0);
122        _speedPanel.setLocation(_controlPanel.getWidth(), _functionPanel.getHeight());
123
124        JDesktopPane desktop = new JDesktopPane();
125        getContentPane().add(desktop);
126        desktop.add(_controlPanelJIF);
127        desktop.add(_functionPanelJIF);
128        desktop.add(_speedPanel);
129
130        desktop.setPreferredSize(new Dimension(
131                _controlPanelJIF.getWidth() + _functionPanelJIF.getWidth(), _controlPanelJIF.getHeight()));
132
133        setResizable(false);
134        jmri.util.PlaceWindow.getDefault().nextTo(_warrantFrame, null, this);
135        pack();
136    }
137
138    /**
139     * Set up View, Edit and Power Menus
140     */
141    private void initializeMenu() {
142        JMenu speedControl = new JMenu(Bundle.getMessage("SpeedControl"));
143        ButtonGroup buttonGroup = new ButtonGroup();
144        JRadioButtonMenuItem displaySlider = new JRadioButtonMenuItem(Bundle.getMessage("ButtonDisplaySpeedSlider"));
145        displaySlider.addActionListener((ActionEvent e)->
146            _controlPanel.setSpeedController(jmri.jmrit.throttle.panels.ControlPanel.SLIDERDISPLAYCONTINUOUS));
147        displaySlider.setSelected(true);
148        buttonGroup.add(displaySlider);
149        speedControl.add(displaySlider);
150        JRadioButtonMenuItem displaySteps = new JRadioButtonMenuItem(Bundle.getMessage("ButtonDisplaySpeedSteps"));
151        displaySteps.addActionListener((ActionEvent e)->
152            _controlPanel.setSpeedController(jmri.jmrit.throttle.panels.ControlPanel.STEPDISPLAY));
153        buttonGroup.add(displaySteps);
154        speedControl.add(displaySteps);
155        this.setJMenuBar(new JMenuBar());
156        this.getJMenuBar().add(speedControl);
157
158       if (powerMgr != null) {
159            JMenu powerMenu = new JMenu(Bundle.getMessage("ThrottleMenuPower"));
160            JMenuItem powerOn = new JMenuItem(Bundle.getMessage("ThrottleMenuPowerOn"));
161            powerMenu.add(powerOn);
162            powerOn.addActionListener((ActionEvent e) -> {
163                try {
164                    powerMgr.setPower(PowerManager.ON);
165                } catch (JmriException e1) {
166                    log.error("Error when setting power", e1);
167                }
168            });
169
170            JMenuItem powerOff = new JMenuItem(Bundle.getMessage("ThrottleMenuPowerOff"));
171            powerMenu.add(powerOff);
172            powerOff.addActionListener((ActionEvent e) -> {
173                try {
174                    powerMgr.setPower(PowerManager.OFF);
175                } catch (JmriException e1) {
176                    log.error("Error when setting power", e1);
177                }
178            });
179
180            this.getJMenuBar().add(powerMenu);
181        }
182        // add help selection
183        addHelpMenu("package.jmri.jmrit.throttle.ThrottleFrame", true);
184    }
185
186    @Override
187    public void dispose() {
188        _controlPanel.dispose();
189        _functionPanel.dispose();
190        _speedPanel.dispose();
191        _controlPanelJIF.dispose();
192        _functionPanelJIF.dispose();
193        super.dispose();
194    }
195
196    /* Record throttle commands that have been sent to the throttle from ControlPanel */
197
198    protected void setSpeedSetting(float speed) {
199        _warrantFrame.setSpeedCommand(speed);
200    }
201
202    protected void setSpeedStepMode(SpeedStepMode speedStep) {
203        _warrantFrame.setThrottleCommand("SpeedStep", speedStep.name);
204    }
205
206    protected void setFunctionState(String fNum, boolean isSet) {
207        _warrantFrame.setThrottleCommand(fNum, Boolean.toString(isSet));
208    }
209
210    protected void setFunctionLock(String fMom, boolean isLockable) {
211        _warrantFrame.setThrottleCommand(fMom, Boolean.toString(isLockable));
212    }
213
214    protected void setButtonForward(boolean isForward) {
215        _warrantFrame.setThrottleCommand("Forward", Boolean.toString(isForward));
216    }
217
218    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LearnThrottleFrame.class);
219
220}