diff --git a/bbbb.syjs b/bbbb.syjs new file mode 100644 index 0000000..e69de29 diff --git a/gewgew.sypy b/gewgew.sypy new file mode 100644 index 0000000..386bc48 --- /dev/null +++ b/gewgew.sypy @@ -0,0 +1 @@ +wrgvbwrgvewqgeq \ No newline at end of file diff --git a/gregerggtrtg34.syjs b/gregerggtrtg34.syjs new file mode 100644 index 0000000..1e614cf --- /dev/null +++ b/gregerggtrtg34.syjs @@ -0,0 +1,5 @@ +var message = "Hello World!"; +var x = 5; +print(message); +notify(message+" X is "+x+"."); + diff --git a/lib/absolutelayout/AbsoluteLayout.jar b/lib/absolutelayout/AbsoluteLayout.jar new file mode 100644 index 0000000..92b9bf0 Binary files /dev/null and b/lib/absolutelayout/AbsoluteLayout.jar differ diff --git a/lib/nblibraries.properties b/lib/nblibraries.properties index 125167e..b6c4270 100644 --- a/lib/nblibraries.properties +++ b/lib/nblibraries.properties @@ -1,3 +1,6 @@ +libs.absolutelayout.classpath=\ + ${base}/absolutelayout/AbsoluteLayout.jar +libs.absolutelayout.displayName=Absolute Layout # # Apocalypse Laboratories # Open Source License diff --git a/lib/org-netbeans-api-visual.jar b/lib/org-netbeans-api-visual.jar new file mode 100644 index 0000000..c812499 Binary files /dev/null and b/lib/org-netbeans-api-visual.jar differ diff --git a/lib/org-openide-util.jar b/lib/org-openide-util.jar new file mode 100644 index 0000000..0d0c33a Binary files /dev/null and b/lib/org-openide-util.jar differ diff --git a/rgrwgwr.syjs b/rgrwgwr.syjs new file mode 100644 index 0000000..bc9adf6 --- /dev/null +++ b/rgrwgwr.syjs @@ -0,0 +1,4 @@ +var message = "Hello World!"; +var x = 5; +print(message); +notify(message+" X is "+x+"."); \ No newline at end of file diff --git a/src/net/apocalypselabs/symat/CodeEditor.java b/src/net/apocalypselabs/symat/CodeEditor.java index 37a73e7..c260d72 100644 --- a/src/net/apocalypselabs/symat/CodeEditor.java +++ b/src/net/apocalypselabs/symat/CodeEditor.java @@ -68,6 +68,8 @@ public class CodeEditor extends javax.swing.JInternalFrame { private CompletionProvider pycomp = new CodeCompleter("py").getProvider(); private AutoCompletion jsac = new AutoCompletion(jscomp); private AutoCompletion pyac = new AutoCompletion(pycomp); + + private String filename = ""; /** * Creates new form CodeEditor @@ -435,6 +437,7 @@ public class CodeEditor extends javax.swing.JInternalFrame { File f = fc.getSelectedFile(); codeBox.setText(readFile(f.toString(), StandardCharsets.UTF_8)); isSaved = true; + filename = f.toString(); lastSaved = codeBox.getText(); setTitle("Editor - " + f.getName()); } catch (IOException ex) { @@ -484,6 +487,7 @@ public class CodeEditor extends javax.swing.JInternalFrame { jsac.uninstall(); pyac.install(codeBox); } + filename = file; } private void saveMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveMenuActionPerformed @@ -492,13 +496,14 @@ public class CodeEditor extends javax.swing.JInternalFrame { if (r == JFileChooser.APPROVE_OPTION) { try { saveFile(codeBox.getText(), addSaveExt(fc.getSelectedFile().toString())); + filename = fc.getSelectedFile().toString(); } catch (IOException ex) { JOptionPane.showInternalMessageDialog(this, "Error: Cannot save file: " + ex.getMessage()); } } } else { try { - saveFile(codeBox.getText(), addSaveExt(fc.getSelectedFile().toString())); + saveFile(codeBox.getText(), addSaveExt(filename)); } catch (IOException ex) { JOptionPane.showInternalMessageDialog(this, "Error: Cannot save file: " + ex.getMessage()); } @@ -682,6 +687,7 @@ public class CodeEditor extends javax.swing.JInternalFrame { setTitle("Editor - " + (new File(path)).getName()); lastSaved = content; isSaved = true; + MainGUI.addRecentFile(path); } @Override diff --git a/src/net/apocalypselabs/symat/KeyValListItem.java b/src/net/apocalypselabs/symat/KeyValListItem.java new file mode 100644 index 0000000..f3b836f --- /dev/null +++ b/src/net/apocalypselabs/symat/KeyValListItem.java @@ -0,0 +1,94 @@ +/* + * Apocalypse Laboratories + * Open Source License + * + * Source code can be used for any purpose, as long as: + * - Compiled binaries are rebranded and trademarks are not + * visible by the end user at any time, except to give + * credit to Apocalypse Laboratories, such as by showing + * "Based on by Apocalypse Laboratories" or a + * similar notice; + * - You do not use the code for evil; + * - Rebranded compiled applications have significant + * differences in functionality; + * - and you provide your modified source code for download, + * under the terms of the GNU LGPL v3 or a comparable + * license. + * + * Compiled binaries cannot be redistributed or mirrored, + * unless: + * - You have written permission from Apocalypse Laboratories; + * - Downloads are not available from Apocalypse Laboratories, + * not even behind a paywall or other blocking mechanism; + * - or you have received a multi-computer license, in which + * case you should take measures to prevent unauthorized + * downloads, such as preventing download access from the + * Internet. + */ +package net.apocalypselabs.symat; + +/** + * A simple key/value pair for lists and stuff. + * @author Skylar + */ +public class KeyValListItem { + // I know, not Java code standards. + // But it's easier and cleaner this way. + private String VAL = ""; + private String KEY = ""; + + public KeyValListItem() { + + } + + public KeyValListItem(String key) { + KEY = key; + } + + public KeyValListItem(String key, String val) { + KEY = key; + VAL = val; + } + + /** + * Get the key. + * @return the key. + */ + @Override + public String toString() { + return KEY; + } + + /** + * Get the value of this pair. + * @return duh. + */ + public String getValue() { + return VAL; + } + + /** + * Set the key. + *
To get it back use toString(). + * @param key the key. + */ + public void setKey(String key) { + KEY = key; + } + + /** + * Set the value for this pair. + * @param value + */ + public void setValue(String value) { + VAL = value; + } + + /** + * Is this pair populated? + * @return True if key and value are empty. + */ + public boolean isEmpty() { + return (KEY.equals("") && VAL.equals("")); + } +} diff --git a/src/net/apocalypselabs/symat/MainGUI.form b/src/net/apocalypselabs/symat/MainGUI.form index 7ebd808..fba09d7 100644 --- a/src/net/apocalypselabs/symat/MainGUI.form +++ b/src/net/apocalypselabs/symat/MainGUI.form @@ -332,7 +332,10 @@ - + + + + @@ -340,8 +343,10 @@ - - + + + + @@ -350,11 +355,114 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/net/apocalypselabs/symat/MainGUI.java b/src/net/apocalypselabs/symat/MainGUI.java index 9c5958f..c9a10f2 100644 --- a/src/net/apocalypselabs/symat/MainGUI.java +++ b/src/net/apocalypselabs/symat/MainGUI.java @@ -32,6 +32,7 @@ import java.awt.Graphics; import java.awt.event.KeyEvent; import java.beans.PropertyVetoException; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -40,14 +41,16 @@ import java.util.Calendar; import java.util.Date; import javax.swing.ImageIcon; import javax.swing.JInternalFrame; +import javax.swing.ListModel; /** * This class is like the Force: A light theme, a dark theme, and it binds the - * app together. Also like duct tape, but that's not as cool. + * app together. Also like duct tape, but that's not as cool. * * @author Skylar */ public class MainGUI extends javax.swing.JFrame { + // TODO: Add more code comments and stuff in case anybody else reads this public static final String APP_NAME = "SyMAT 1.0"; public static final double APP_CODE = 12; @@ -57,6 +60,10 @@ public class MainGUI extends javax.swing.JFrame { public static boolean skipPython = false; // Skip python init on start? public static boolean skipEditor = false; // Skip editor init on start? + private static boolean recentItemsMinimized = false; + + private static final int RECENT_FILES = 10; + /** * Creates the main app window and does some quick things that aren't * threaded in SplashScreen. @@ -131,6 +138,7 @@ public class MainGUI extends javax.swing.JFrame { if (argfile.equals("") && !loaded) { loadFrame(new Interpreter()); } + loadRecentFiles(); updateDisplay(); } @@ -185,6 +193,44 @@ public class MainGUI extends javax.swing.JFrame { jLabel3.setText(namemark()); } + public static void loadRecentFiles() { + String files = PrefStorage.getSetting("recentfiles"); + if (files.equals("")) { + return; + } + String[] fileList = files.split("\n"); + KeyValListItem[] items = new KeyValListItem[fileList.length]; + for (int i = 0; i < fileList.length; i++) { + if (i < RECENT_FILES) { + File file = new File(fileList[i]); + if (file.isFile()) { + items[i] = new KeyValListItem(file.getName(), file.getPath()); + } + } + } + + recentFileList.setListData(items); + } + + public static void addRecentFile(String file) { + String files = PrefStorage.getSetting("recentfiles"); + String[] fileList = files.split("\n"); + for (int i = 0; i < fileList.length; i++) { + if (fileList[i].trim().equals(file)) { + fileList[i] = ""; + } + } + files = file + "\n"; + for (String f : fileList) { + if (!f.trim().equals("")) { + files += f + "\n"; + } + } + PrefStorage.saveSetting("recentfiles", files); + PrefStorage.save(); + loadRecentFiles(); + } + /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -220,6 +266,11 @@ public class MainGUI extends javax.swing.JFrame { } ; jLabel2 = new javax.swing.JLabel(); + recentItemsPanel = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + recentFileList = new javax.swing.JList(); + recentFileBtn = new javax.swing.JButton(); + recentItemsTitle = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle(APP_NAME); @@ -400,7 +451,72 @@ public class MainGUI extends javax.swing.JFrame { mainPane.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); mainPane.setOpaque(false); - jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/net/apocalypselabs/symat/images/watermark.png"))); // NOI18N + jLabel2.setFont(new java.awt.Font("Tahoma", 0, 48)); // NOI18N + jLabel2.setForeground(new java.awt.Color(153, 153, 153)); + jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + jLabel2.setText("SyMAT"); + jLabel2.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); + + recentItemsPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + recentItemsPanel.setForeground(new java.awt.Color(153, 153, 153)); + recentItemsPanel.setMaximumSize(new java.awt.Dimension(160, 234)); + recentItemsPanel.setOpaque(false); + + recentFileList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + recentFileList.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + recentFileListMouseClicked(evt); + } + }); + recentFileList.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() { + public void mouseMoved(java.awt.event.MouseEvent evt) { + recentFileListMouseMoved(evt); + } + }); + jScrollPane1.setViewportView(recentFileList); + + recentFileBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/net/apocalypselabs/symat/icons/openfile.png"))); // NOI18N + recentFileBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + recentFileBtnActionPerformed(evt); + } + }); + + recentItemsTitle.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N + recentItemsTitle.setForeground(new java.awt.Color(102, 102, 102)); + recentItemsTitle.setText(" Recent Files"); + recentItemsTitle.setOpaque(true); + recentItemsTitle.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + recentItemsTitleMouseClicked(evt); + } + }); + + javax.swing.GroupLayout recentItemsPanelLayout = new javax.swing.GroupLayout(recentItemsPanel); + recentItemsPanel.setLayout(recentItemsPanelLayout); + recentItemsPanelLayout.setHorizontalGroup( + recentItemsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(recentItemsPanelLayout.createSequentialGroup() + .addGroup(recentItemsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(recentItemsPanelLayout.createSequentialGroup() + .addGap(97, 97, 97) + .addComponent(recentFileBtn)) + .addGroup(recentItemsPanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 136, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(recentItemsTitle, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + recentItemsPanelLayout.setVerticalGroup( + recentItemsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(recentItemsPanelLayout.createSequentialGroup() + .addComponent(recentItemsTitle) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 167, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(recentFileBtn) + .addContainerGap()) + ); javax.swing.GroupLayout mainPaneLayout = new javax.swing.GroupLayout(mainPane); mainPane.setLayout(mainPaneLayout); @@ -408,17 +524,22 @@ public class MainGUI extends javax.swing.JFrame { mainPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPaneLayout.createSequentialGroup() .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(mainPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(recentItemsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); mainPaneLayout.setVerticalGroup( mainPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPaneLayout.createSequentialGroup() - .addContainerGap(295, Short.MAX_VALUE) - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 175, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap() + .addComponent(recentItemsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 189, Short.MAX_VALUE) + .addComponent(jLabel2) .addContainerGap()) ); mainPane.setLayer(jLabel2, javax.swing.JLayeredPane.DEFAULT_LAYER); + mainPane.setLayer(recentItemsPanel, javax.swing.JLayeredPane.DEFAULT_LAYER); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); @@ -480,6 +601,53 @@ public class MainGUI extends javax.swing.JFrame { loadFrame(new Interpreter()); }//GEN-LAST:event_shellBtnActionPerformed + private void recentFileBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recentFileBtnActionPerformed + if (recentFileList.getSelectedValue() == null) { + return; + } + KeyValListItem file = (KeyValListItem) recentFileList.getSelectedValue(); + if (file.isEmpty()) { + return; + } + CodeEditor edit = new CodeEditor(); + edit.openFileFromName(file.getValue()); + loadFrame(edit); + }//GEN-LAST:event_recentFileBtnActionPerformed + + private void recentFileListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_recentFileListMouseClicked + if (evt.getClickCount() == 2) { + recentFileBtnActionPerformed(null); + } + }//GEN-LAST:event_recentFileListMouseClicked + + private void recentFileListMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_recentFileListMouseMoved + try { + ListModel m = recentFileList.getModel(); + int index = recentFileList.locationToIndex(evt.getPoint()); + if (index > -1) { + recentFileList.setToolTipText( + ((KeyValListItem) m.getElementAt(index)).getValue()); + } + } catch (Exception ex) { + // This feature is optional. Just skip it if it's broken. + recentFileList.setToolTipText(""); + } + }//GEN-LAST:event_recentFileListMouseMoved + + private void recentItemsTitleMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_recentItemsTitleMouseClicked + if (evt.getClickCount() == 2) { + if (recentItemsMinimized) { + recentItemsPanel.setSize(recentItemsPanel.getWidth(), + (int) recentItemsPanel.getMaximumSize().getHeight()); + recentItemsMinimized = false; + } else { + recentItemsPanel.setSize(recentItemsPanel.getWidth(), + recentItemsTitle.getHeight()); + recentItemsMinimized = true; + } + } + }//GEN-LAST:event_recentItemsTitleMouseClicked + /* End the button handlers. */ @@ -616,7 +784,12 @@ public class MainGUI extends javax.swing.JFrame { public static javax.swing.JLabel jLabel3; public static javax.swing.JPanel jPanel2; public static javax.swing.JPanel jPanel4; + public static javax.swing.JScrollPane jScrollPane1; public static javax.swing.JDesktopPane mainPane; + public static javax.swing.JButton recentFileBtn; + public static javax.swing.JList recentFileList; + public static javax.swing.JPanel recentItemsPanel; + public static javax.swing.JLabel recentItemsTitle; public static javax.swing.JButton shellBtn; public static javax.swing.JTabbedPane tabs; // End of variables declaration//GEN-END:variables diff --git a/src/net/apocalypselabs/symat/SplashScreen.java b/src/net/apocalypselabs/symat/SplashScreen.java index 005f27f..2892ad8 100644 --- a/src/net/apocalypselabs/symat/SplashScreen.java +++ b/src/net/apocalypselabs/symat/SplashScreen.java @@ -111,7 +111,7 @@ public class SplashScreen extends javax.swing.JFrame { if (!MainGUI.skipPython) { // Python laggggsss when used for first time, this fixes the wait later. System.out.println("Warming up Python engine, to skip run with argument 'skippython'"); - setProgress(20, "Initializing code engine..."); + setProgress(15, "Initializing code engine..."); try { CodeRunner python = new CodeRunner(true); } catch (Exception ex) { @@ -121,11 +121,12 @@ public class SplashScreen extends javax.swing.JFrame { if (!MainGUI.skipEditor) { System.out.println("Preparing editor, to skip run with argument 'skipeditor'"); - setProgress(50, "Preparing editor..."); + setProgress(60, "Preparing editor..."); // Get editor going too CodeEditor edit = new CodeEditor(); } - setProgress(70, "Loading main interface..."); + + setProgress(85, "Loading main interface..."); new MainGUI().setVisible(true); setProgress(100, "Done!"); dispose(); @@ -149,47 +150,6 @@ public class SplashScreen extends javax.swing.JFrame { } }); } - - /** - * Animate the dots on the progress bar label. - * - * This way people know it's not "frozen", so they don't "let it go". - */ - private class DotThread extends Thread { - - private boolean doRun = true; - - @Override - public void run() { - while (doRun) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - String val = progBar.getString(); - if (val.endsWith("...")) { - progBar.setString(val.replace("...", " ")); - } else if (val.endsWith(".. ")) { - progBar.setString(val.replace(".. ", "...")); - } else if (val.endsWith(". ")) { - progBar.setString(val.replace(". ", ".. ")); - } else if (!val.endsWith(" ")) { - progBar.setString(val + ". "); - } - } - }); - Debug.println("dotsupdate"); - try { - Thread.sleep(500); - } catch (InterruptedException ex) { - - } - } - } - - public void kill() { - doRun = false; - } - } } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel jLabel5; diff --git a/src/net/apocalypselabs/symat/icons/openfile.png b/src/net/apocalypselabs/symat/icons/openfile.png new file mode 100644 index 0000000..63a7e6d Binary files /dev/null and b/src/net/apocalypselabs/symat/icons/openfile.png differ diff --git a/testpath.syjs b/testpath.syjs new file mode 100644 index 0000000..30d74d2 --- /dev/null +++ b/testpath.syjs @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/tewgewqgewq.sypy b/tewgewqgewq.sypy new file mode 100644 index 0000000..386bc48 --- /dev/null +++ b/tewgewqgewq.sypy @@ -0,0 +1 @@ +wrgvbwrgvewqgeq \ No newline at end of file