16 Commits 57bf41a741 ... bd56287da4

Author SHA1 Message Date
  UltrasonicMadness bd56287da4 Preparing to release version 0.2.0 6 years ago
  UltrasonicMadness 49bd18f623 The preferences window is now a fixed size 6 years ago
  UltrasonicMadness f5639ae255 Added Adwaita icons to replace the unicode characters 6 years ago
  UltrasonicMadness ee22e80e57 Fixed layout problems which occurred when songs with long titles were played 6 years ago
  UltrasonicMadness 9043d45f41 Centred windows 6 years ago
  UltrasonicMadness 6dab482e76 Cleaned up main method 6 years ago
  UltrasonicMadness b580aa6584 Improved the thread running SoundHelix, it no longer spam-prints when not playing a song 6 years ago
  UltrasonicMadness 79c79afc7e Added tooltips and fixed keyboard shortcuts 6 years ago
  UltrasonicMadness d84606ce4f Added the SoundHelix-Guitar style from the SourceForge repo 6 years ago
  UltrasonicMadness a886319412 Iconified buttons 6 years ago
  UltrasonicMadness 304368528d Added keyboard shortcuts 6 years ago
  UltrasonicMadness 6f29c09355 Added VersionUtils module 6 years ago
  UltrasonicMadness 9badaf38a0 Made the MIDI output directory configurable 6 years ago
  UltrasonicMadness 36c0af5990 Added a separate dialog for advanced options and disabled MIDI export by default 6 years ago
  UltrasonicMadness 7109d0270c Changed to Allman coding style, consistent with my other projects 6 years ago
  UltrasonicMadness 983a1380ac Removed references to 'UltrasonicHelix' in the comments 6 years ago

+ 1 - 0
README.md

@@ -12,6 +12,7 @@ Run the ant command in the main folder and then run the generated MadHelix.jar f
 ## Credits
 * SoundHelix is developed by Thomas Schürger
 * MadHelix is developed by UltrasonicMadness
+* The icons are made by the [GNOME Project](http://www.gnome.org/) as part of version 3.28.0 of the [Adwaita Icon Theme](https://gitlab.gnome.org/GNOME/adwaita-icon-theme).
 
 ## License
 MadHelix is available under the GNU General Public License, version 3 only.

+ 4 - 0
build.xml

@@ -1,5 +1,6 @@
 <project name="MadHelix" basedir="." default="jar">
     <property name="srcdir" location="src" />
+    <property name="resdir" location="res" />
     <property name="targetdir" location="bin" />
     <property name="jarfile" location="MadHelix.jar" />
     
@@ -11,6 +12,9 @@
     <target name="compile">
         <mkdir dir="${targetdir}" />
         <javac srcdir="${srcdir}" destdir="${targetdir}" classpath="lib/SoundHelix.jar" />
+        <copy todir="${targetdir}">
+            <fileset dir="res" />
+        </copy>
     </target>
     
     <target name="jar" depends="compile">

BIN
res/icons/help-about.png


BIN
res/icons/media-playback-start.png


BIN
res/icons/media-playback-stop.png


BIN
res/icons/preferences-system.png


+ 200 - 88
src/org/ultrasonicmadness/madhelix/MadHelix.java

@@ -1,5 +1,5 @@
 /*
- * UltrasonicHelix is a Java Swing-based GUI frontend for SoundHelix.
+ * MadHelix is a Java Swing-based GUI frontend for SoundHelix.
  * Copyright (C) 2018 UltrasonicMadness
  *
  * This program is free software: you can redistribute it and/or modify
@@ -32,34 +32,41 @@ import java.awt.GridBagLayout;
 import java.awt.GridBagConstraints;
 import java.awt.Insets;
 
+// AWT events
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+
 // Swing widgets
+import javax.swing.AbstractAction;
+import javax.swing.ImageIcon;
 import javax.swing.JButton;
-import javax.swing.JCheckBox;
 import javax.swing.JComboBox;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JTextField;
+import javax.swing.KeyStroke;
 
 // Other Swing modules
 import javax.swing.SwingUtilities;
 
-// UltrasonicHelix imports
+// MadHelix imports
 import org.ultrasonicmadness.madhelix.dialogs.AboutBox;
+import org.ultrasonicmadness.madhelix.dialogs.PrefsDialog;
 import org.ultrasonicmadness.madhelix.utils.PathUtils;
 
-public class MadHelix extends JFrame {
-    
+
+public class MadHelix extends JFrame
+{
     // SoundHelix
     private final File stylesDir = new File(PathUtils.getStylesDirPath()); // Styles directory
-    private SongContext currentSong; // Current song being played
-    private boolean startHelix = false; // If this is set to true, SoundHelix will be called to play the specified music and it will be set back to false.
-    private boolean helixPlaying = false; // Set to true while SoundHelix is playing music, false otherwise.
+    private SongContext currentSong = null; // Current song being played
     
-    // MIDI file output
-    private final File midiOutDir = new File(PathUtils.getMidiDirPath()); // MIDI file output directory
-    private boolean exportMidi = true;
+    // Preferences
+    private File midiOutDir = new File(PathUtils.getMidiDirPath());
+    private boolean exportingMidi = false;
     
     // Main 3 panels: status, options, controls
     private JPanel statusPanel = new JPanel();
@@ -69,6 +76,7 @@ public class MadHelix extends JFrame {
     // Components
     private JPanel mainPanel = new JPanel();
     private AboutBox aboutBox = new AboutBox(this);
+    private PrefsDialog prefsDialog = new PrefsDialog(this);
     
     // Status labels (spaces included so that the layout works)
     private JLabel playStatus = new JLabel(" ");
@@ -81,35 +89,35 @@ public class MadHelix extends JFrame {
     private JTextField songNameEntry = new JTextField(24);
     private JLabel styleLabel = new JLabel("Style");
     private JComboBox<String> styleChoice = new JComboBox<>();
-    private JCheckBox fileExportCheckBox = new JCheckBox("Export files when playing", exportMidi);
+    
+    // Icons
+    private ImageIcon playIcon = new ImageIcon(this.getClass()
+            .getResource("/icons/media-playback-start.png"), "Play");
+    
+    private ImageIcon stopIcon = new ImageIcon(this.getClass()
+            .getResource("/icons/media-playback-stop.png"), "Stop");
+    
+    private ImageIcon prefsIcon = new ImageIcon(this.getClass()
+            .getResource("/icons/preferences-system.png"), "Preferences");
+    
+    private ImageIcon aboutIcon = new ImageIcon(this.getClass()
+            .getResource("/icons/help-about.png"), "About MadHelix");
     
     // Control buttons
-    private JButton playButton = new JButton("\u25B6");
-    private JButton stopButton = new JButton("\u25A0");
-    private JButton aboutButton = new JButton("About");
+    private JButton playButton = new JButton(playIcon);
+    private JButton stopButton = new JButton(stopIcon);
+    private JButton prefsButton = new JButton(prefsIcon);
+    private JButton aboutButton = new JButton(aboutIcon);
     
     // SoundHelix thread.
-    private Thread soundHelix = new Thread(new Runnable() {
-        public void run() {
-            // This thread runs as long as UltrasonicHelix does.
-            while (true) {
-                if (startHelix) {
-                    // Since this command has been started, set this to false so it isn't started repeatedly.
-                    startHelix = false;
-                    playSong();
-                    
-                } else {
-                    // Without this, the thread does not respond to startHelix being set to true.
-                    // There is probably a much better way to do this.
-                    System.out.print("");
-                }
-            }
-        }
-        
-        private void playSong() {
-            helixPlaying = true;
-            
+    private Thread soundHelix = null;
+    
+    private Thread genSoundHelixThread()
+    {
+        Thread newHelixThread = new Thread(() ->
+        {
             setStatus("Loading SoundHelix");
+            this.setTitle("Loading SoundHelix - MadHelix");
             
             // The buttons don't function at this time, so disable them while SoundHelix loads.
             setControlsEnabled(false);
@@ -120,26 +128,33 @@ public class MadHelix extends JFrame {
             File styleFile = new File(stylesDir.toString() + File.separator +
                     styleName + ".xml");
             
-            try {
+            try
+            {
                 // If a song name is specified, use it, otherwise generate a random number and use it.
-                if (songName != null && !songName.equals("")) {
+                if (songName != null && !songName.equals(""))
+                {
                     currentSong = SongUtils.generateSong(
                             styleFile.toURI().toURL(), songName);
-                } else {
+                }
+                else
+                {
                     // This is the same way SoundHelix uses the random number generator.
                     currentSong = SongUtils.generateSong(
                             styleFile.toURI().toURL(), new Random().nextLong());
                 }
                 
-                if (exportMidi) {
-                    
-                    try {
+                if (exportingMidi)
+                {
+                    try
+                    {
                         MidiPlayer midiPlayer = (MidiPlayer)currentSong.getPlayer();
                         
                         midiPlayer.setMidiFilename(midiOutDir + File.separator + 
                                 currentSong.getSongName() + "-" + styleName +
                                 ".mid");
-                    } catch (Exception x) {
+                    }
+                    catch (Exception x)
+                    {
                         JOptionPane.showMessageDialog(null, x.getMessage().toString(),
                                 "Could not set MIDI filename.", JOptionPane.ERROR_MESSAGE);
                     }
@@ -149,18 +164,24 @@ public class MadHelix extends JFrame {
                 setStatus("Playing",
                         currentSong.getSongName(), "Style", styleName);
                 
+                this.setTitle(currentSong.getSongName() + " - MadHelix");
+                
                 // Now SoundHelix has loaded, enable the buttons again
                 setControlsEnabled(true);
                 
                 // Play the song
                 currentSong.getPlayer().play(currentSong);
-            } catch (Exception x) { // In case SoundHelix encounters a problem
+            }
+            catch (Exception x) // In case SoundHelix encounters a problem
+            {
                 JOptionPane.showMessageDialog(null, x.getMessage().toString(),
                         "Exception occurred", JOptionPane.ERROR_MESSAGE);
                 
                 // In case an error has occured, enable the buttons again
                 setControlsEnabled(true);
-            } catch (NoClassDefFoundError r) { // In case SoundHelix.jar is not found
+            }
+            catch (NoClassDefFoundError r) // In case SoundHelix.jar is not found
+            {
                 JOptionPane.showMessageDialog(null,
                         "Cannot find module " + r.getMessage(), "Error",
                         JOptionPane.ERROR_MESSAGE);
@@ -170,19 +191,22 @@ public class MadHelix extends JFrame {
             }
             
             // The song has finished at this point, so update variables and status accordingly.
-            helixPlaying = false;
             setStatus("Ready");
-        }
-    });
+            this.setTitle("MadHelix");
+        });
+        
+        newHelixThread.setDaemon(true); // Closes SoundHelix if MadHelix is closed.
+        return newHelixThread;
+    }
     
-    public MadHelix() {
+    public MadHelix()
+    {
         initMadHelix();
     }
     
-    private void initMadHelix() {
-        // Start SoundHelix thread
-        soundHelix.setDaemon(true); // Closes SoundHelix if UltrasonicHelix is closed.
-        soundHelix.start();
+    private void initMadHelix()
+    {
+        setUpKeyBindings();
         
         addComponents();
         
@@ -191,15 +215,18 @@ public class MadHelix extends JFrame {
         this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
         this.setResizable(false);
         this.pack();
+        this.setLocationRelativeTo(null);
         this.setVisible(true);
     }
     
-    private void determineStatus() {
+    private void determineStatus()
+    {
         // Assume program is ready , then check for errors
         setStatus("Ready");
         
         // If no styles are found, disable the buttons and display an alert.
-        if (stylesDir.list() == null || stylesDir.list().length == 0) {
+        if (stylesDir.list() == null || stylesDir.list().length == 0)
+        {
             setStatus("No styles available.");
             setControlsEnabled(false);
             
@@ -211,13 +238,58 @@ public class MadHelix extends JFrame {
         }
     }
     
-    private void addComponents() {
+    private void setUpKeyBindings()
+    {
+        // Play is CTRL+P or return
+        playButton.getInputMap(JButton.WHEN_IN_FOCUSED_WINDOW)
+                .put(KeyStroke.getKeyStroke(KeyEvent.VK_P,
+                InputEvent.CTRL_DOWN_MASK), "play");
+        
+        playButton.getActionMap().put("play", new AbstractAction()
+        {
+            @Override
+            public void actionPerformed(ActionEvent ev)
+            {
+                playSong();
+            }
+        });
+        
+        playButton.getInputMap(JButton.WHEN_IN_FOCUSED_WINDOW)
+                .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "play");
+        
+        playButton.getActionMap().put("play", new AbstractAction()
+        {
+            @Override
+            public void actionPerformed(ActionEvent ev)
+            {
+                playSong();
+            }
+        });
+        
+        // Stop is CTRL+S
+        stopButton.getInputMap(JButton.WHEN_IN_FOCUSED_WINDOW)
+                .put(KeyStroke.getKeyStroke(KeyEvent.VK_S,
+                InputEvent.CTRL_DOWN_MASK), "stop");
+        
+        stopButton.getActionMap().put("stop", new AbstractAction()
+        {
+            @Override
+            public void actionPerformed(ActionEvent ev)
+            {
+                stopSong();
+            }
+        });
+    }
+    
+    private void addComponents()
+    {
         // Set panel layout
         mainPanel.setLayout(new GridBagLayout());
         
         // Set up constraints
         GridBagConstraints mainConstraints = new GridBagConstraints();
         mainConstraints.fill = GridBagConstraints.HORIZONTAL;
+        mainConstraints.weightx = 1;
         
         addStatusLabels();
         addOptions();
@@ -236,7 +308,8 @@ public class MadHelix extends JFrame {
         this.add(mainPanel);
     }
     
-    private void addStatusLabels() {
+    private void addStatusLabels()
+    {
         determineStatus();
         
         // Set up layout
@@ -264,7 +337,8 @@ public class MadHelix extends JFrame {
     
     // Set status to the four passed strings
     private void setStatus(String newPlayStatus, String newPlayStatusInfo,
-        String newStyleStatus, String newStyleStatusInfo) {
+            String newStyleStatus, String newStyleStatusInfo)
+    {
         
         // Set all label text to the passed strings.
         playStatus.setText(newPlayStatus);
@@ -274,26 +348,22 @@ public class MadHelix extends JFrame {
     }
     
     // Set status to the passed string. The others are reset to blank.
-    private void setStatus(String newPlayStatus) {
+    private void setStatus(String newPlayStatus)
+    {
         setStatus(newPlayStatus, " ", " ", " ");
     }
     
-    private void addOptions() {
+    private void addOptions()
+    {
         // Get list of styles for the combo box.
         String[] styleList = PathUtils.getStyles();
         
         // Add styles to style choice combo box
-        for (String style : styleList) {        
+        for (String style : styleList)
+        {        
             styleChoice.addItem(style);
         }
         
-        fileExportCheckBox.addActionListener(ev -> {
-            exportMidi = fileExportCheckBox.isSelected();
-        });
-        
-        fileExportCheckBox.setToolTipText("The files are exported to the midi directory " + 
-                "in the same location as the JAR application.");
-        
         // Set up layout
         optionsPanel.setLayout(new GridBagLayout());
         
@@ -303,33 +373,47 @@ public class MadHelix extends JFrame {
         
         // Add song information
         constraints.gridy = 0;
+        constraints.weightx = 0;
         optionsPanel.add(songNameLabel, constraints);
+        constraints.weightx = 1;
         optionsPanel.add(songNameEntry, constraints);
         
         // Add style label
         constraints.gridy = 1;
+        constraints.weightx = 0;
         optionsPanel.add(styleLabel, constraints);
+        constraints.weightx = 1;
         optionsPanel.add(styleChoice, constraints);
-        
-        // Add file export checkbox
-        constraints.gridy = 2;
-        constraints.gridwidth = 2;
-        optionsPanel.add(fileExportCheckBox, constraints);
     }
     
-    private void addControls() {
+    private void addControls()
+    {
+        // Add tooltips to the buttons
+        playButton.setToolTipText("Play");
+        stopButton.setToolTipText("Stop");
+        prefsButton.setToolTipText("Preferences");
+        aboutButton.setToolTipText("About MadHelix");
+        
         // Set up layout
         controlsPanel.setLayout(new GridBagLayout());
         
-        playButton.addActionListener(ev -> {
+        playButton.addActionListener(ev ->
+        {
             playSong();
         });
         
-        stopButton.addActionListener(ev -> {
+        stopButton.addActionListener(ev ->
+        {
             stopSong();
         });
         
-        aboutButton.addActionListener(ev -> {
+        prefsButton.addActionListener(ev ->
+        {
+            prefsDialog.setVisible(true);
+        });
+        
+        aboutButton.addActionListener(ev ->
+        {
             aboutBox.setVisible(true);
         });
         
@@ -346,40 +430,68 @@ public class MadHelix extends JFrame {
         controlsPanel.add(new JPanel(), constraints);
         
         constraints.weightx = 0;
+        controlsPanel.add(prefsButton, constraints);
         controlsPanel.add(aboutButton, constraints);
     }
     
-    private void setControlsEnabled(boolean enabled) {
+    private void setControlsEnabled(boolean enabled)
+    {
         playButton.setEnabled(enabled);
         stopButton.setEnabled(enabled);
     }
     
     // The current song name entered in the text box. This may be different from the name of the song currently playing.
-    private String getCurrentSongName() {
+    private String getCurrentSongName()
+    {
         return songNameEntry.getText();
     }
     
     // Refer to the comment above regarding song names, the same applies here with styles.
-    private String getCurrentStyleName() {
+    private String getCurrentStyleName()
+    {
         return styleChoice.getSelectedItem().toString();
     }
     
-    private void playSong() {
+    private void playSong()
+    {
         stopSong(); // Without this, the next song won't play until the last one is finished.
-        startHelix = true; // Signals to the SoundHelix thread to start
+        soundHelix = genSoundHelixThread();
+        soundHelix.start();
     }
     
-    private void stopSong() {
-        if (helixPlaying) {
+    private void stopSong()
+    {
+        if (currentSong != null)
+        {
             currentSong.getPlayer().abortPlay();
         }
     }
     
-    public static void main(String[] args) {
-        SwingUtilities.invokeLater(new Runnable() {
-            public void run() {
-                new MadHelix();
-            }
+    public boolean isExportingMidi()
+    {
+       return exportingMidi;
+    }
+    
+    public void setExportingMidi(boolean exportingMidi)
+    {
+       this.exportingMidi = exportingMidi;
+    }
+    
+    public File getMidiOutDir()
+    {
+        return midiOutDir;
+    }
+    
+    public void setMidiOutDir(File midiOutDir)
+    {
+        this.midiOutDir = midiOutDir;
+    }
+    
+    public static void main(String[] args)
+    {
+        SwingUtilities.invokeLater(() ->
+        {
+            new MadHelix();
         });
     }
 }

+ 38 - 19
src/org/ultrasonicmadness/madhelix/dialogs/AboutBox.java

@@ -1,5 +1,5 @@
 /*
- * UltrasonicHelix is a Java Swing-based GUI frontend for SoundHelix.
+ * MadHelix is a Java Swing-based GUI frontend for SoundHelix.
  * Copyright (C) 2018 UltrasonicMadness
  *
  * This program is free software: you can redistribute it and/or modify
@@ -18,7 +18,7 @@
 package org.ultrasonicmadness.madhelix.dialogs;
 
 // Get SoundHelix version
-import com.soundhelix.util.VersionUtils;
+import org.ultrasonicmadness.madhelix.utils.VersionUtils;
 
 // AWT widgets
 import java.awt.BorderLayout;
@@ -41,19 +41,22 @@ import javax.swing.JScrollPane;
 import javax.swing.JTabbedPane;
 import javax.swing.JTextArea;
 
-public class AboutBox extends JDialog {
+public class AboutBox extends JDialog
+{
     private JPanel infoPanel = new JPanel();
     private JTabbedPane mainPane = new JTabbedPane();
     private JPanel creditsPanel = new JPanel();
     private JPanel licensePanel = new JPanel();
     private JPanel buttonPanel = new JPanel();
     
-    public AboutBox(JFrame mainWindow) {
+    public AboutBox(JFrame mainWindow)
+    {
         super(mainWindow, true);
         initAboutBox();
     }
     
-    private void initAboutBox() {
+    private void initAboutBox()
+    {
         // Declare and initialize objects
         this.setTitle("About");
         JPanel mainPanel = new JPanel();
@@ -87,24 +90,34 @@ public class AboutBox extends JDialog {
         
         // Set up the main window
         this.add(mainPanel);
-        this.pack();
+        this.setSize(540, 405);
         this.setResizable(false);
+        this.setLocationRelativeTo(null);
     }
     
-    private void setUpInfoPanel() {
+    private void setUpInfoPanel()
+    {
         infoPanel.setLayout(new GridBagLayout());
         
         // Set up labels
-        JLabel headerLabel = new JLabel("MadHelix 0.1.0");
-        JLabel descriptionLabel = new JLabel("A Java Swing frontend for the SoundHelix music generation tool.");
+        JLabel headerLabel = new JLabel("MadHelix " +
+                VersionUtils.getMadHelixVersionAsString());
+        JLabel descriptionLabel = new JLabel("A Java Swing frontend for " +
+                "the SoundHelix music generation tool.");
         JLabel helixVersionLabel = new JLabel();
         
         // In case an error occurs or SoundHelix.jar cannot be found
-        try {
-            helixVersionLabel.setText("Using SoundHelix version: " + VersionUtils.getVersion());
-        } catch (Exception e) {
+        try
+        {
+            helixVersionLabel.setText("Using SoundHelix version: " +
+                    VersionUtils.getSoundHelixVersionAsString());
+        }
+        catch (Exception e)
+        {
             helixVersionLabel.setText(e.getMessage().toString());
-        } catch (NoClassDefFoundError e) {
+        }
+        catch (NoClassDefFoundError e)
+        {
             helixVersionLabel.setText("Cannot find module " + e.getMessage());
         }
         
@@ -126,7 +139,8 @@ public class AboutBox extends JDialog {
         infoPanel.add(helixVersionLabel, constraints);
     }
     
-    private void setUpMainPane() {
+    private void setUpMainPane()
+    {
         setUpCreditsPanel();
         setUpLicensePanel();
         
@@ -135,7 +149,8 @@ public class AboutBox extends JDialog {
         mainPane.add("License", licensePanel);
     }
     
-    private void setUpCreditsPanel() {
+    private void setUpCreditsPanel()
+    {
         // Set up text area
         JTextArea textArea = new JTextArea();
         
@@ -145,14 +160,16 @@ public class AboutBox extends JDialog {
         textArea.setEditable(false);
         textArea.setText(
             "UltrasonicMadness <contact@ultrasonicmadness.org> - MadHelix developer\n" +
-            "Thomas Sch\u00FCrger <thomas@schuerger.com> - SoundHelix developer"
+            "Thomas Sch\u00FCrger <thomas@schuerger.com> - SoundHelix developer\n" + 
+            "GNOME Project <http://www.gnome.org/> - Icons from the Adwaita Icon Theme"
         );
         
         // Add objects to main frame
         creditsPanel.add(new JScrollPane(textArea));
     }
     
-    private void setUpLicensePanel() {
+    private void setUpLicensePanel()
+    {
         // Set up text area
         JTextArea textArea = new JTextArea();
         
@@ -178,7 +195,8 @@ public class AboutBox extends JDialog {
         licensePanel.add(new JScrollPane(textArea));
     }
     
-    private void setUpButtonPanel() {
+    private void setUpButtonPanel()
+    {
         // Set up the button
         JButton closeButton = new JButton("Close");
         
@@ -186,7 +204,8 @@ public class AboutBox extends JDialog {
         buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
         
         // Add listener to button
-        closeButton.addActionListener(e -> {
+        closeButton.addActionListener(e ->
+        {
             this.dispose();
         });
         

+ 197 - 0
src/org/ultrasonicmadness/madhelix/dialogs/PrefsDialog.java

@@ -0,0 +1,197 @@
+/*
+ * MadHelix is a Java Swing-based GUI frontend for SoundHelix.
+ * Copyright (C) 2018 UltrasonicMadness
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.ultrasonicmadness.madhelix.dialogs;
+
+// Assorted imports
+import java.io.File;
+
+// AWT widgets
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+// Swing widgets
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+// MadHelix imports
+import org.ultrasonicmadness.madhelix.MadHelix;
+
+public class PrefsDialog extends JDialog
+{
+    // The settings are stored in the main window if the OK button is clicked.
+    private MadHelix mainWindow;
+    
+    // Components
+    private JPanel prefsPanel = new JPanel();
+    private JPanel fileLocationPanel = new JPanel();
+    private JPanel buttonPanel = new JPanel();
+    private JFileChooser fileChooser = new JFileChooser();
+    
+    // Option components
+    JCheckBox fileExportCheckBox;
+    JTextField fileLocationField = new JTextField();
+    
+    // Initial options
+    boolean initExportingMidi;
+    
+    // Options
+    boolean exportingMidi;
+    
+    public PrefsDialog(MadHelix mainWindow)
+    {
+        super(mainWindow, true);
+        this.mainWindow = mainWindow;
+        initExportingMidi = mainWindow.isExportingMidi();
+        setUpSettingsDialog();
+    }
+    
+    private void setUpSettingsDialog()
+    {
+        this.setTitle("MadHelix preferences");
+        JPanel mainPanel = new JPanel();
+        
+        setUpPrefsPanel();
+        setUpButtonPanel();
+        
+        mainPanel.setLayout(new GridBagLayout());
+        
+        GridBagConstraints constraints = new GridBagConstraints();
+        constraints.insets = new Insets(4, 4, 4, 4);
+        constraints.fill = GridBagConstraints.BOTH;
+        constraints.weightx = 1;
+        
+        constraints.gridy = 0;
+        constraints.weighty = 1;
+        mainPanel.add(prefsPanel, constraints);
+        
+        constraints.gridy = 1;
+        constraints.weighty = 0;
+        mainPanel.add(buttonPanel, constraints);
+        
+        this.add(mainPanel);
+        this.pack();
+        this.setResizable(false);
+        this.setSize(320, 160);
+        this.setLocationRelativeTo(null);
+    }
+    
+    private void setUpPrefsPanel()
+    {
+        fileExportCheckBox = new JCheckBox("Export MIDI files when playing",
+                mainWindow.isExportingMidi());
+        
+        fileExportCheckBox.addActionListener(ev ->
+        {
+            exportingMidi = fileExportCheckBox.isSelected();
+        });
+        
+        setUpFileLocationPanel();
+        
+        GridBagConstraints constraints = new GridBagConstraints();
+        constraints.insets = new Insets(4, 4, 4, 4);
+        constraints.fill = GridBagConstraints.BOTH;
+        constraints.weightx = 1;
+        
+        prefsPanel.setLayout(new GridBagLayout());
+        
+        constraints.gridy = 0;
+        prefsPanel.add(fileLocationPanel, constraints);
+        
+        constraints.gridy = 1;
+        prefsPanel.add(fileExportCheckBox, constraints);
+    }
+    
+    private void setUpFileLocationPanel()
+    {
+        JLabel fileLocationLabel = new JLabel("MIDI output directory",
+                JLabel.LEFT);
+        JButton fileBrowseButton = new JButton("Browse...");
+        
+        fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+        fileLocationField.setText(mainWindow.getMidiOutDir().toString());
+        
+        fileBrowseButton.addActionListener(ev ->
+        {
+            int fileStatus = fileChooser.showOpenDialog(this);
+            
+            // If 'Open' is clicked
+            if (fileStatus == 0)
+            {
+                fileLocationField.setText(fileChooser.getSelectedFile().toString());
+            }
+        });
+        
+        fileLocationPanel.setLayout(new GridBagLayout());
+        GridBagConstraints constraints = new GridBagConstraints();
+        constraints.fill = GridBagConstraints.BOTH;
+        
+        constraints.gridwidth = 2;
+        constraints.gridy = 0;
+        fileLocationPanel.add(fileLocationLabel, constraints);
+        
+        constraints.gridwidth = 1;
+        constraints.gridy = 1;
+        
+        constraints.gridx = 0;
+        constraints.weightx = 1;
+        fileLocationPanel.add(fileLocationField, constraints);
+        
+        constraints.gridx = 1;
+        constraints.weightx = 0;
+        fileLocationPanel.add(fileBrowseButton, constraints);
+    }
+    
+    private void setUpButtonPanel()
+    {
+        JButton okButton = new JButton("OK");
+        JButton cancelButton = new JButton("Cancel");
+        
+        // Set up the layout
+        buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+        
+        // Add listeners to buttons
+        okButton.addActionListener(e ->
+        {
+            initExportingMidi = exportingMidi;
+            mainWindow.setExportingMidi(initExportingMidi);
+            mainWindow.setMidiOutDir(new File(fileLocationField.getText()));
+            
+            this.dispose();
+        });
+        
+        cancelButton.addActionListener(e ->
+        {
+            fileExportCheckBox.setSelected(initExportingMidi);
+            fileLocationField.setText(mainWindow.getMidiOutDir().toString());
+            
+            this.dispose();
+        });
+        
+        // Add the button to the panel
+        buttonPanel.add(okButton);
+        buttonPanel.add(cancelButton);
+    }
+}

+ 0 - 0
src/org/ultrasonicmadness/madhelix/utils/PathUtils.java


Some files were not shown because too many files changed in this diff