/** * Copyright 2012 Tobias Gierke <tobias.gierke@code-sourcery.de> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.codesourcery.jasm16.ide.ui.views; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import javax.swing.BorderFactory; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListCellRenderer; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import org.apache.commons.lang.StringUtils; import de.codesourcery.jasm16.emulator.EmulationOptions; import de.codesourcery.jasm16.emulator.EmulationOptions.InsertedDisk; import de.codesourcery.jasm16.emulator.IEmulator.EmulationSpeed; public abstract class EmulationOptionsView extends AbstractView { public static final String ID = "emulation_options"; private JPanel panel; // general emulation properties private final JCheckBox box1 = new JCheckBox("Write-protected memory of executed instructions (slow) ?"); private final JCheckBox box2 = new JCheckBox("Enable debug output ?"); private final JCheckBox box3 = new JCheckBox("Ignore access to unused device slots ?"); private final JCheckBox box8 = new JCheckBox("Halt on store to immediate value ?"); // keyboard emulation private final JCheckBox box4 = new JCheckBox("Use legacy key buffer ?"); // video emulation private final JCheckBox box5 = new JCheckBox("Map video ram to 0x8000 on startup ?"); private final JCheckBox box6 = new JCheckBox("Map font ram to 0x8180 on startup ?"); // emulator options private JPanel emulatorPanel = new JPanel(); private final DefaultComboBoxModel<EmulationSpeed> speedModel = new DefaultComboBoxModel<EmulationSpeed>(EmulationSpeed.values()); private final JComboBox<EmulationSpeed> speedBox = new JComboBox<EmulationSpeed>(speedModel); // disk drive private final JPanel diskDrivePanel = new JPanel(); private final JCheckBox box7 = new JCheckBox("Run floppy emulation at max speed ?"); private final JTextField selectedFileField = new JTextField(); private final JButton fileChooserButton = new JButton("Choose image..."); private final JCheckBox writeProtected = new JCheckBox("write-protected"); public EmulationOptionsView() { emulatorPanel.setLayout( new GridBagLayout() ); GridBagConstraints cnstrs = constraints( 0, 0 , false, false , GridBagConstraints.NONE ); emulatorPanel.add( new JLabel("Emulation speed"), cnstrs ); cnstrs = constraints( 1, 0 , true , true , GridBagConstraints.NONE ); cnstrs.anchor=GridBagConstraints.WEST; emulatorPanel.setBorder( BorderFactory.createTitledBorder("General options") ); speedBox.setRenderer( new DefaultListCellRenderer() { public Component getListCellRendererComponent(javax.swing.JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { final java.awt.Component result = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if ( value != null ) { switch( (EmulationSpeed) value ) { case MAX_SPEED: setText("Max."); break; case REAL_SPEED: setText("100 kHz"); break; default: setText( value.toString() ); break; } } return result; }; } ); emulatorPanel.add( speedBox , cnstrs ); // disk drive panel selectedFileField.setColumns( 25 ); diskDrivePanel.setLayout( new GridBagLayout() ); cnstrs = constraints( 0, 0 , false , true , GridBagConstraints.NONE ); cnstrs.anchor = GridBagConstraints.CENTER; diskDrivePanel.setBorder( BorderFactory.createTitledBorder("Disk drive") ); diskDrivePanel.add( selectedFileField , cnstrs ); cnstrs = constraints( 1, 0 , false , true , GridBagConstraints.NONE ); cnstrs.anchor = GridBagConstraints.CENTER; diskDrivePanel.add( fileChooserButton , cnstrs ); fileChooserButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { final JFileChooser chooser; if ( getSelectedFile() != null ) { chooser = new JFileChooser( getSelectedFile().getParentFile() ); } else { chooser = new JFileChooser(); } final int result = chooser.showOpenDialog(null); if ( result == JFileChooser.APPROVE_OPTION && chooser.getSelectedFile().isFile() ) { selectedFileField.setText( chooser.getSelectedFile().getAbsolutePath() ); } } } ); cnstrs = constraints( 2, 0 , false , true , GridBagConstraints.NONE ); cnstrs.anchor = GridBagConstraints.CENTER; diskDrivePanel.add( writeProtected , cnstrs ); } public void setData(EmulationOptions options) { if (options == null) { throw new IllegalArgumentException("options must not be null"); } box1.setSelected( options.isMemoryProtectionEnabled() ); box2.setSelected( options.isEnableDebugOutput() ); box3.setSelected( options.isIgnoreAccessToUnknownDevices() ); box4.setSelected( options.isUseLegacyKeyboardBuffer() ); box8.setSelected( options.isCrashOnStoreWithImmediate() ); // video emulation box5.setSelected( options.isMapVideoRamUponAddDevice() ); box6.setSelected( options.isMapFontRamUponAddDevice() ); // emulation speed panel speedModel.setSelectedItem( options.getEmulationSpeed() ); box7.setSelected( options.isRunFloppyAtFullSpeed() ); // floppy emulation speed final InsertedDisk disk = options.getInsertedDisk(); if ( disk == null ) { selectedFileField.setText( null ); writeProtected.setSelected( false ); } else { selectedFileField.setText( disk.getFile().getAbsolutePath() ); writeProtected.setSelected( disk.isWriteProtected() ); } } @Override public final void refreshDisplay() { } protected abstract void onSave(EmulationOptions options); protected abstract void onCancel(); @Override public final String getTitle() { return "Emulation options"; } private void saveChangesTo(EmulationOptions options) { options.setMemoryProtectionEnabled( box1.isSelected() ); options.setEnableDebugOutput( box2.isSelected() ); options.setIgnoreAccessToUnknownDevices( box3.isSelected() ); options.setCrashOnStoreWithImmediate( box8.isSelected() ); options.setUseLegacyKeyboardBuffer( box4.isSelected() ); options.setMapVideoRamUponAddDevice( box5.isSelected() ); options.setMapFontRamUponAddDevice( box6.isSelected() ); options.setRunFloppyAtFullSpeed( box7.isSelected() ); options.setEmulationSpeed( (EmulationSpeed) speedBox.getSelectedItem() ); if ( getSelectedFile() != null ) { options.setInsertedDisk( new InsertedDisk(getSelectedFile(),writeProtected.isSelected() ) ); } else { options.setInsertedDisk( null ); } } private File getSelectedFile() { final String path = selectedFileField.getText(); return StringUtils.isBlank( path ) ? null : new File(path); } @Override public final String getID() { return ID; } @Override protected final JPanel getPanel() { if ( panel == null ) { panel = createPanel(); } return panel; } private JPanel createPanel() { final JPanel result = new JPanel(); result.setLayout( new GridBagLayout() ); // 'Memory protection' checkbox int y = 0; GridBagConstraints cnstrs = constraints( 0 , y++ , true , false , GridBagConstraints.HORIZONTAL ); cnstrs.gridwidth=2; result.add( box1 , cnstrs ); cnstrs = constraints( 0 , y++ , true , false , GridBagConstraints.HORIZONTAL ); cnstrs.gridwidth=2; result.add( box2 , cnstrs ); cnstrs = constraints( 0 , y++ , true , false , GridBagConstraints.HORIZONTAL ); cnstrs.gridwidth=2; result.add( box3 , cnstrs ); cnstrs = constraints( 0 , y++ , true , false , GridBagConstraints.HORIZONTAL ); cnstrs.gridwidth=2; result.add( box8 , cnstrs ); cnstrs = constraints( 0 , y++ , true , false , GridBagConstraints.HORIZONTAL ); cnstrs.gridwidth=2; result.add( box4 , cnstrs ); cnstrs = constraints( 0 , y++ , true , false , GridBagConstraints.HORIZONTAL ); cnstrs.gridwidth=2; result.add( box5 , cnstrs ); cnstrs = constraints( 0 , y++ , true , false , GridBagConstraints.HORIZONTAL ); cnstrs.gridwidth=2; result.add( box6 , cnstrs ); cnstrs = constraints( 0 , y++ , true , false , GridBagConstraints.HORIZONTAL ); cnstrs.gridwidth=2; result.add( box7 , cnstrs ); cnstrs = constraints( 0 , y++ , true , false , GridBagConstraints.HORIZONTAL ); cnstrs.gridwidth=2; result.add( diskDrivePanel , cnstrs ); cnstrs = constraints( 0 , y++ , true , false , GridBagConstraints.HORIZONTAL ); cnstrs.gridwidth=2; result.add( emulatorPanel , cnstrs ); // cancel button cnstrs = constraints( 0 , y , false , false , GridBagConstraints.NONE ); cnstrs.weightx = 0.33; cnstrs.anchor = GridBagConstraints.CENTER; final JButton cancelButton = new JButton("Cancel"); cancelButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { onCancel(); } } ); result.add( cancelButton , cnstrs ); // save button cnstrs = constraints( 1 , y , true , false , GridBagConstraints.NONE ); cnstrs.weightx = 0.33; cnstrs.anchor = GridBagConstraints.CENTER; final JButton saveButton = new JButton("Save"); saveButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { final EmulationOptions options = new EmulationOptions(); saveChangesTo( options ); onSave( options ); } } ); result.add( saveButton , cnstrs ); return result; } }