diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index cb6690ab1..12beb4754 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -111,9 +111,9 @@ public class Base { try { createAndShowGUI(args); } catch (Throwable t) { - Messages.showBadnessTrace("It was not meant to be", - "A serious problem happened during startup. Please report:\n" + - "http://github.com/processing/processing/issues/new", t, true); + Messages.showTrace("It was not meant to be", + "A serious problem happened during startup. Please report:\n" + + "http://github.com/processing/processing/issues/new", t, true); } } }); @@ -209,7 +209,7 @@ public class Base { try { new Welcome(base, prompt); } catch (IOException e) { - Messages.showBadnessTrace("Unwelcoming", + Messages.showTrace("Unwelcoming", "Please report this error to\n" + "https://github.com/processing/processing/issues", e, false); } @@ -224,7 +224,7 @@ public class Base { // show this one so that it's not truncated in the error window. t = t.getCause(); } - Messages.showBadnessTrace("We're off on the wrong foot", + Messages.showTrace("We're off on the wrong foot", "An error occurred during startup.", t, true); } Messages.log("done creating base..."); //$NON-NLS-1$ @@ -915,11 +915,11 @@ public class Base { "Try updating the Mode or contact its author for a new version.", nsme); } catch (Throwable t) { if (nextMode.equals(getDefaultMode())) { - Messages.showBadnessTrace("Serious Problem", + Messages.showTrace("Serious Problem", "An unexpected, unknown, and unrecoverable error occurred\n" + "while opening a new editor window. Please report this.", t, true); } else { - Messages.showBadnessTrace("Mode Problems", + Messages.showTrace("Mode Problems", "A nasty error occurred while trying to use " + nextMode.getTitle() + ".\n" + "It may not be compatible with this version of Processing.\n" + "Try updating the Mode or contact its author for a new version.", t, false); @@ -943,7 +943,7 @@ public class Base { */ } catch (Throwable t) { - Messages.showBadnessTrace("Terrible News", + Messages.showTrace("Terrible News", "A serious error occurred while " + "trying to create a new editor window.", t, nextMode == getDefaultMode()); // quit if default diff --git a/app/src/processing/app/Messages.java b/app/src/processing/app/Messages.java index 3be3f312e..07e1a6247 100644 --- a/app/src/processing/app/Messages.java +++ b/app/src/processing/app/Messages.java @@ -155,7 +155,7 @@ public class Messages { /** * Testing a new warning window that includes the stack trace. */ - static void showBadnessTrace(String title, String message, + static public void showTrace(String title, String message, Throwable t, boolean fatal) { if (title == null) title = fatal ? "Error" : "Warning"; diff --git a/app/src/processing/app/contrib/ContributionListPanel.java b/app/src/processing/app/contrib/ContributionListPanel.java index af24b4c6e..af02f4886 100644 --- a/app/src/processing/app/contrib/ContributionListPanel.java +++ b/app/src/processing/app/contrib/ContributionListPanel.java @@ -59,6 +59,8 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib protected ContributionListing contribListing = ContributionListing.getInstance(); protected JTable table; DefaultTableModel dtm; + JScrollPane scrollPane; + Font myFont; public ContributionListPanel() { // TODO Auto-generated constructor stub @@ -96,11 +98,12 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib return c; } }; - + // There is a space before Status String[] colName = { " Status", "Name", "Author" }; dtm.setColumnIdentifiers(colName); - JScrollPane scrollPane = new JScrollPane(table); + scrollPane = new JScrollPane(table); + scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); table.setFillsViewportHeight(true); // table.setBorder(); table.setDefaultRenderer(Contribution.class, new StatusRendere()); @@ -345,9 +348,11 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib label.setFont(ContributionManagerDialog.myFont); label.setOpaque(true); } else { - label = new JLabel( - contribution.isSpecial() ? Toolkit - .getLibIcon("icons/pde-16.png") : null); + if (contribution.isSpecial()) { + label = new JLabel(Toolkit.getLibIcon("icons/foundation-16.png")); + } else { + label = new JLabel(); + } String authorList = contribution.getAuthorList(); String name = getAuthorNameWithoutMarkup(authorList); label.setText(name.toString()); @@ -379,7 +384,7 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib return Contribution.class; } } - + String getAuthorNameWithoutMarkup(String authorList) { StringBuilder name = new StringBuilder(""); if (authorList != null) { diff --git a/app/src/processing/app/contrib/ContributionManager.java b/app/src/processing/app/contrib/ContributionManager.java index 559bce665..2dc791121 100644 --- a/app/src/processing/app/contrib/ContributionManager.java +++ b/app/src/processing/app/contrib/ContributionManager.java @@ -38,11 +38,7 @@ import processing.data.StringDict; public class ContributionManager { - static public final ContributionListing contribListing; - - static { - contribListing = ContributionListing.getInstance(); - } + static final ContributionListing listing = ContributionListing.getInstance(); /** @@ -72,9 +68,9 @@ public class ContributionManager { if (post == null) { conn.setRequestMethod("GET"); conn.connect(); + } else { post = gzipEncode(post); - conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Encoding", "gzip"); @@ -178,7 +174,7 @@ public class ContributionManager { ad.install(editor.getBase(), contribZip, false, status); if (contribution != null) { - contribListing.replaceContribution(ad, contribution); + listing.replaceContribution(ad, contribution); if (contribution.getType() == ContributionType.MODE) { List contribModes = editor.getBase().getModeContribs(); if (!contribModes.contains(contribution)) { @@ -263,7 +259,7 @@ public class ContributionManager { false, null); if (contribution != null) { - contribListing.replaceContribution(ad, contribution); + listing.replaceContribution(ad, contribution); if (contribution.getType() == ContributionType.MODE) { List contribModes = base.getModeContribs(); if (contribModes != null && !contribModes.contains(contribution)) { @@ -396,7 +392,7 @@ public class ContributionManager { false, null); if (contribution != null) { - contribListing.replaceContribution(ad, contribution); + listing.replaceContribution(ad, contribution); if (base.getActiveEditor() != null) { refreshInstalled(base.getActiveEditor()); } @@ -432,11 +428,8 @@ public class ContributionManager { } - static public void refreshInstalled(Editor e) { - - Iterator iter = e.getBase().getEditors().iterator(); - while (iter.hasNext()) { - Editor ed = iter.next(); + static void refreshInstalled(Editor e) { + for (Editor ed : e.getBase().getEditors()) { ed.getMode().rebuildImportMenu(); ed.getMode().rebuildExamplesFrame(); ed.rebuildToolMenu(); @@ -502,7 +495,6 @@ public class ContributionManager { * Also updates all entries previously marked for update. */ static public void cleanup(final Base base) throws Exception { - deleteTemp(Base.getSketchbookModesFolder()); deleteTemp(Base.getSketchbookToolsFolder()); @@ -530,8 +522,6 @@ public class ContributionManager { }; s.execute(); - - clearRestartFlags(Base.getSketchbookModesFolder()); clearRestartFlags(Base.getSketchbookToolsFolder()); } @@ -545,32 +535,23 @@ public class ContributionManager { * @param root */ static private void deleteTemp(File root) { - - LinkedList deleteList = new LinkedList(); - - for (File f : root.listFiles()) - if (f.getName().matches(root.getName().substring(0, 4) + "\\d*" + "tmp")) - deleteList.add(f); - - Iterator folderIter = deleteList.iterator(); - - while (folderIter.hasNext()) { - Util.removeDir(folderIter.next()); + String pattern = root.getName().substring(0, 4) + "\\d*" + "tmp"; + for (File f : root.listFiles()) { + if (f.getName().matches(pattern)) { + Util.removeDir(f); + } } } /** * Deletes all the modes/tools/libs that are flagged for removal. - * - * @param root - * @throws Exception */ static private void deleteFlagged(File root) throws Exception { File[] markedForDeletion = root.listFiles(new FileFilter() { public boolean accept(File folder) { - return (folder.isDirectory() && LocalContribution - .isDeletionFlagged(folder)); + return (folder.isDirectory() && + LocalContribution.isDeletionFlagged(folder)); } }); for (File folder : markedForDeletion) { @@ -590,19 +571,16 @@ public class ContributionManager { static private void installPreviouslyFailed(Base base, File root) throws Exception { File[] installList = root.listFiles(new FileFilter() { public boolean accept(File folder) { - return (folder.isFile()); + return folder.isFile(); } }); for (File file : installList) { - Iterator iter = contribListing.advertisedContributions.iterator(); - while (iter.hasNext()) { - AvailableContribution availableContrib = iter.next(); - if (file.getName().equals(availableContrib.getName())) { + for (AvailableContribution contrib : listing.advertisedContributions) { + if (file.getName().equals(contrib.getName())) { file.delete(); - installOnStartUp(base, availableContrib); - contribListing - .replaceContribution(availableContrib, availableContrib); + installOnStartUp(base, contrib); + listing.replaceContribution(contrib, contrib); } } } @@ -619,8 +597,8 @@ public class ContributionManager { static private void updateFlagged(Base base, File root) throws Exception { File[] markedForUpdate = root.listFiles(new FileFilter() { public boolean accept(File folder) { - return (folder.isDirectory() && LocalContribution - .isUpdateFlagged(folder)); + return (folder.isDirectory() && + LocalContribution.isUpdateFlagged(folder)); } }); @@ -643,7 +621,7 @@ public class ContributionManager { Util.removeDir(folder); } - Iterator iter = contribListing.advertisedContributions.iterator(); + Iterator iter = listing.advertisedContributions.iterator(); while (iter.hasNext()) { AvailableContribution availableContribs = iter.next(); if (updateContribsNames.contains(availableContribs.getName())) { @@ -655,7 +633,7 @@ public class ContributionManager { while (iter2.hasNext()) { AvailableContribution contribToUpdate = iter2.next(); installOnStartUp(base, contribToUpdate); - contribListing.replaceContribution(contribToUpdate, contribToUpdate); + listing.replaceContribution(contribToUpdate, contribToUpdate); } } diff --git a/app/src/processing/app/contrib/ContributionPanel.java b/app/src/processing/app/contrib/ContributionPanel.java index c6730b2c6..9690ae038 100644 --- a/app/src/processing/app/contrib/ContributionPanel.java +++ b/app/src/processing/app/contrib/ContributionPanel.java @@ -447,8 +447,8 @@ class ContributionPanel extends JPanel { this.contrib = contrib; if (contrib.isSpecial()) { - ImageIcon processingIcon = Toolkit.getLibIcon("icons/pde-48.png"); - JLabel iconLabel = new JLabel(processingIcon); + JLabel iconLabel = + new JLabel(Toolkit.getLibIcon("icons/foundation-32.png")); // was 48? iconLabel.setBorder(new EmptyBorder(4, 7, 7, 7)); iconLabel.setVerticalAlignment(SwingConstants.TOP); add(iconLabel, BorderLayout.WEST); @@ -462,7 +462,7 @@ class ContributionPanel extends JPanel { description.append("" + contrib.getName() + ""); } description.append(" "); - + String version = contrib.getPrettyVersion(); // TODO this has no place here, we shouldn't be cleaning up contrib @@ -476,7 +476,7 @@ class ContributionPanel extends JPanel { description.append(version); } description.append("
"); - + String authorList = contrib.getAuthorList(); if (authorList != null && !authorList.isEmpty()) { description.append(toHtmlLinks(contrib.getAuthorList())); diff --git a/app/src/processing/app/contrib/ContributionTab.java b/app/src/processing/app/contrib/ContributionTab.java index d4623b02b..44b0aa2fd 100644 --- a/app/src/processing/app/contrib/ContributionTab.java +++ b/app/src/processing/app/contrib/ContributionTab.java @@ -25,6 +25,7 @@ package processing.app.contrib; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; +import java.awt.Graphics; import java.awt.event.*; import java.util.*; @@ -135,7 +136,15 @@ public class ContributionTab { progressBar = new JProgressBar(); progressBar.setVisible(false); createComponents(); - panel = new JPanel(false); + panel = new JPanel(false){ + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + g.setColor(new Color(0xe0fffd)); + g.fillRect(getX(), panel.getY() - ContributionManagerDialog.TAB_HEIGHT - 2 , panel.getWidth(), 2); + + } + }; loaderLabel = new JLabel(Toolkit.getLibIcon("manager/loader.gif")); loaderLabel.setOpaque(false); loaderLabel.setBackground(Color.WHITE); @@ -188,6 +197,7 @@ public class ContributionTab { });*/ + int catChooserWidth = ContributionManagerDialog.AUTHOR_WIDTH + contributionListPanel.scrollPane.getVerticalScrollBar().getPreferredSize().width - 10; GroupLayout layout = new GroupLayout(panel); panel.setLayout(layout); @@ -206,9 +216,9 @@ public class ContributionTab { .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) .addComponent(categoryChooser, - ContributionManagerDialog.AUTHOR_WIDTH - 10, - ContributionManagerDialog.AUTHOR_WIDTH - 10, - ContributionManagerDialog.AUTHOR_WIDTH - 10) + catChooserWidth, + catChooserWidth, + catChooserWidth) .addContainerGap()).addComponent(loaderLabel) .addComponent(contributionListPanel).addComponent(errorPanel) .addComponent(statusPanel)); @@ -373,6 +383,7 @@ public class ContributionTab { List libraries = new ArrayList(editor.getMode().contribLibraries); + libraries.addAll(editor.getMode().coreLibraries); contributions.addAll(libraries); //ArrayList tools = editor.contribTools; diff --git a/app/src/processing/app/contrib/StatusPanel.java b/app/src/processing/app/contrib/StatusPanel.java index d20989196..895d24138 100644 --- a/app/src/processing/app/contrib/StatusPanel.java +++ b/app/src/processing/app/contrib/StatusPanel.java @@ -29,7 +29,6 @@ import java.awt.event.ActionListener; import javax.swing.GroupLayout; import javax.swing.Icon; -import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; @@ -44,6 +43,7 @@ import processing.app.ui.Toolkit; import processing.app.Base; import processing.app.Platform; + class StatusPanel extends JPanel { static final int BUTTON_WIDTH = 150; @@ -216,15 +216,13 @@ class StatusPanel extends JPanel { } public void update(ContributionPanel panel) { - progressBarPanel.removeAll(); + Icon icon = null; if (panel.getContrib().isSpecial()) { - Icon contribIcon = new ImageIcon(Toolkit.getLibImage("/icons/pde-48.png")); - iconLabel.setIcon(contribIcon); - } else { - iconLabel.setIcon(null); + icon = Toolkit.getLibIcon("icons/foundation-32.png"); // was 48? } + iconLabel.setIcon(icon); label.setText(panel.description.toString()); ((HTMLDocument)label.getDocument()).getStyleSheet().addRule(bodyRule); @@ -232,8 +230,8 @@ class StatusPanel extends JPanel { && (contributionListing.hasUpdates(panel.getContrib()) && !panel .getContrib().isUpdateFlagged())); - String latestVersion = contributionListing.getLatestVersion(panel - .getContrib()); + String latestVersion = + contributionListing.getLatestVersion(panel.getContrib()); String currentVersion = panel.getContrib().getPrettyVersion(); if (latestVersion != null) { diff --git a/app/src/processing/app/contrib/UpdateContributionTab.java b/app/src/processing/app/contrib/UpdateContributionTab.java index a1791a860..b0a7eda51 100644 --- a/app/src/processing/app/contrib/UpdateContributionTab.java +++ b/app/src/processing/app/contrib/UpdateContributionTab.java @@ -3,6 +3,7 @@ package processing.app.contrib; import java.awt.Color; import java.awt.Component; import java.awt.Font; +import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Comparator; @@ -52,7 +53,15 @@ public class UpdateContributionTab extends ContributionTab { progressBar = new JProgressBar(); progressBar.setVisible(false); buildErrorPanel(); - panel = new JPanel(false); + panel = new JPanel(false){ + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + g.setColor(new Color(0xe0fffd)); + g.fillRect(getX(), panel.getY() - ContributionManagerDialog.TAB_HEIGHT - 2 , panel.getWidth(), 2); + + } + }; loaderLabel = new JLabel(Toolkit.getLibIcon("icons/loader.gif")); loaderLabel.setOpaque(false); loaderLabel.setBackground(Color.WHITE); @@ -68,6 +77,7 @@ public class UpdateContributionTab extends ContributionTab { layout.setVerticalGroup(layout .createSequentialGroup() + .addGap(2) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER) .addComponent(loaderLabel) .addComponent(contributionListPanel)) diff --git a/app/src/processing/app/platform/WindowsPlatform.java b/app/src/processing/app/platform/WindowsPlatform.java index c3731bc92..cb336dc39 100644 --- a/app/src/processing/app/platform/WindowsPlatform.java +++ b/app/src/processing/app/platform/WindowsPlatform.java @@ -501,7 +501,46 @@ public class WindowsPlatform extends DefaultPlatform { // Code partially thanks to Richard Quirk from: // http://quirkygba.blogspot.com/2009/11/setting-environment-variables-in-java.html - static WinLibC clib = (WinLibC) Native.loadLibrary("msvcrt", WinLibC.class); + static WinLibC clib; + + + static WinLibC getLibC() { + if (clib == null) { + try { + clib = (WinLibC) Native.loadLibrary("msvcrt", WinLibC.class); + } catch (UnsatisfiedLinkError ule) { + // Might be a problem with file encoding, use a default directory + // https://github.com/processing/processing/issues/3624 + File ctmp = new File("C:\\TEMP"); // kick it old school + if (ctmp.exists() || ctmp.mkdirs()) { + try { + File jnaTmp = File.createTempFile("processing", "jna", ctmp); + if (jnaTmp.mkdirs()) { + jnaTmp.deleteOnExit(); // clean up when we're done + System.setProperty("jna.tmpdir", jnaTmp.getAbsolutePath()); + try { + clib = (WinLibC) Native.loadLibrary("msvcrt", WinLibC.class); + } catch (UnsatisfiedLinkError ulf) { + Messages.showTrace("No luck with JNA", + "After several attempts, JNA could not be loaded. Please report:\n" + + "http://github.com/processing/processing/issues/new", ulf, true); + } + } + } catch (IOException e) { + Messages.showTrace("Could not create temp directory", + "JNA could not be loaded properly. Please report:\n" + + "http://github.com/processing/processing/issues/new", e, true); + } + } else { + Messages.showError("Could not create temp directory", + "JNA could not be loaded into C:\\TEMP. Please report:\n" + + "http://github.com/processing/processing/issues/new", null); + } + } + } + return clib; + } + public interface WinLibC extends Library { //WinLibC INSTANCE = (WinLibC) Native.loadLibrary("msvcrt", WinLibC.class); @@ -512,7 +551,7 @@ public class WindowsPlatform extends DefaultPlatform { public void setenv(String variable, String value) { //WinLibC clib = WinLibC.INSTANCE; - clib._putenv(variable + "=" + value); + getLibC()._putenv(variable + "=" + value); } @@ -525,7 +564,7 @@ public class WindowsPlatform extends DefaultPlatform { //WinLibC clib = WinLibC.INSTANCE; //clib._putenv(variable + "="); //return 0; - return clib._putenv(variable + "="); + return getLibC()._putenv(variable + "="); } diff --git a/app/src/processing/app/syntax/JEditTextArea.java b/app/src/processing/app/syntax/JEditTextArea.java index b44c7b5b9..1ca163ca2 100644 --- a/app/src/processing/app/syntax/JEditTextArea.java +++ b/app/src/processing/app/syntax/JEditTextArea.java @@ -1286,8 +1286,7 @@ public class JEditTextArea extends JComponent fireCaretEvent(); } - // When the user is typing, etc, we don't want the caret - // to blink + // When the user is typing, etc, we don't want the caret to blink blink = true; if (!DISABLE_CARET) { caretTimer.restart(); @@ -2001,13 +2000,11 @@ public class JEditTextArea extends JComponent protected static String RIGHT = "right"; protected static String BOTTOM = "bottom"; -// protected static JEditTextArea focusedComponent; protected Timer caretTimer; - private boolean DISABLE_CARET = false; + static private final boolean DISABLE_CARET = false; protected TextAreaPainter painter; - //protected EditPopupMenu popup; protected JPopupMenu popup; protected EventListenerList eventListenerList; diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index 8631e847d..8c0586521 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -153,7 +153,6 @@ public abstract class Editor extends JFrame implements RunnerListener { Image backgroundGradient; -// protected Editor(final Base base, String path, int[] location, final Mode mode) { protected Editor(final Base base, String path, final EditorState state, final Mode mode) throws EditorException { super("Processing", state.checkConfig()); @@ -1909,6 +1908,8 @@ public abstract class Editor extends JFrame implements RunnerListener { public void startCompoundEdit() { stopCompoundEdit(); compoundEdit = new CompoundEdit(); + caretUndoStack.push(textarea.getCaretPosition()); + caretRedoStack.clear(); } @@ -1919,8 +1920,6 @@ public abstract class Editor extends JFrame implements RunnerListener { if (compoundEdit != null) { compoundEdit.end(); undo.addEdit(compoundEdit); - caretUndoStack.push(textarea.getCaretPosition()); - caretRedoStack.clear(); undoAction.updateUndoState(); redoAction.updateRedoState(); compoundEdit = null; @@ -2026,6 +2025,7 @@ public abstract class Editor extends JFrame implements RunnerListener { return endUndoEvent != null; } + void startTimerEvent() { endUndoEvent = new TimerTask() { public void run() { @@ -2037,6 +2037,7 @@ public abstract class Editor extends JFrame implements RunnerListener { timer.purge(); } + void endTextEditHistory() { if (endUndoEvent != null) { endUndoEvent.cancel(); @@ -2045,6 +2046,13 @@ public abstract class Editor extends JFrame implements RunnerListener { stopCompoundEdit(); } + + public void removeNotify() { + timer.cancel(); + super.removeNotify(); + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . diff --git a/app/src/processing/app/ui/EditorFooter.java b/app/src/processing/app/ui/EditorFooter.java index 84f972ee0..c97815a99 100644 --- a/app/src/processing/app/ui/EditorFooter.java +++ b/app/src/processing/app/ui/EditorFooter.java @@ -46,24 +46,25 @@ import processing.app.Sketch; */ public class EditorFooter extends Box { // height of this tab bar - static final int HIGH = 29; + static final int HIGH = 32; static final int CURVE_RADIUS = 6; - static final int TAB_TOP = 0; - static final int TAB_BOTTOM = 23; + static final int TAB_TOP = 2; + static final int TAB_BOTTOM = 29; // amount of extra space between individual tabs - static final int TAB_BETWEEN = 3; + static final int TAB_BETWEEN = 2; // amount of margin on the left/right for the text on the tab - static final int MARGIN = 16; + static final int MARGIN = 14; - static final int ICON_WIDTH = 14; - static final int ICON_HEIGHT = 13; - static final int ICON_TOP = 5; + static final int ICON_WIDTH = 16; + static final int ICON_HEIGHT = 16; + static final int ICON_TOP = 7; + static final int ICON_MARGIN = 7; Color[] textColor = new Color[2]; Color[] tabColor = new Color[2]; - Color errorColor; +// Color errorColor; Editor editor; @@ -157,7 +158,7 @@ public class EditorFooter extends Box { tabColor[SELECTED] = mode.getColor("footer.tab.selected.color"); tabColor[UNSELECTED] = mode.getColor("footer.tab.unselected.color"); - errorColor = mode.getColor("status.error.bgcolor"); +// errorColor = mode.getColor("status.error.bgcolor"); gradient = mode.makeGradient("footer", 400, HIGH); } @@ -222,7 +223,11 @@ public class EditorFooter extends Box { } Graphics2D g2 = Toolkit.prepareGraphics(g); - g.drawImage(gradient, 0, 0, imageW, imageH, this); + + g.setColor(tabColor[SELECTED]); + g.fillRect(0, 0, imageW, 2); + + g.drawImage(gradient, 0, 2, imageW, imageH, this); // reset all tab positions for (Tab tab : tabs) { @@ -363,7 +368,7 @@ public class EditorFooter extends Box { int getTextLeft() { int links = left; if (enabledIcon != null) { - links += ICON_WIDTH; + links += ICON_WIDTH + ICON_MARGIN; } return links + ((right - links) - textWidth) / 2; } @@ -375,9 +380,9 @@ public class EditorFooter extends Box { void draw(Graphics g) { int state = isCurrent() ? SELECTED : UNSELECTED; g.setColor(tabColor[state]); - if (notification) { - g.setColor(errorColor); - } +// if (notification) { +// g.setColor(errorColor); +// } Graphics2D g2 = (Graphics2D) g; g2.fill(Toolkit.createRoundRect(left, TAB_TOP, right, TAB_BOTTOM, 0, 0, @@ -385,13 +390,13 @@ public class EditorFooter extends Box { isFirst() ? CURVE_RADIUS : 0)); if (hasIcon()) { - Image icon = isCurrent() ? selectedIcon : enabledIcon; + Image icon = (isCurrent() || notification) ? selectedIcon : enabledIcon; g.drawImage(icon, left + MARGIN, ICON_TOP, ICON_WIDTH, ICON_HEIGHT, null); } int textLeft = getTextLeft(); if (notification && state == UNSELECTED) { - g.setColor(Color.LIGHT_GRAY); + g.setColor(textColor[SELECTED]); } else { g.setColor(textColor[state]); } diff --git a/app/src/processing/app/ui/EditorHeader.java b/app/src/processing/app/ui/EditorHeader.java index 73453e773..e66931419 100644 --- a/app/src/processing/app/ui/EditorHeader.java +++ b/app/src/processing/app/ui/EditorHeader.java @@ -153,7 +153,8 @@ public class EditorHeader extends JComponent { tabColor[UNSELECTED] = mode.getColor("header.tab.unselected.color"); arrowColor = mode.getColor("header.tab.arrow.color"); - modifiedColor = mode.getColor("editor.selection.color"); + //modifiedColor = mode.getColor("editor.selection.color"); + modifiedColor = mode.getColor("header.tab.modified.color"); gradient = mode.makeGradient("header", 400, HIGH); } @@ -358,7 +359,8 @@ public class EditorHeader extends JComponent { if (code.isModified()) { g.setColor(modifiedColor); //g.drawLine(tab.left + NOTCH, top, tab.right - NOTCH, top); - g.drawLine(tab.left + (i == 0 ? CURVE_RADIUS : 0), TAB_TOP, tab.right-1, TAB_TOP); + //g.drawLine(tab.left + (i == 0 ? CURVE_RADIUS : 0), TAB_TOP, tab.right-1, TAB_TOP); + g.drawLine(tab.right, TAB_TOP, tab.right, TAB_BOTTOM); } } diff --git a/build/build.xml b/build/build.xml index 0c58c1ea6..f992dfc38 100644 --- a/build/build.xml +++ b/build/build.xml @@ -64,8 +64,8 @@ --> - - + + @@ -292,11 +292,6 @@ - - - @@ -484,6 +479,12 @@ + + + + @@ -583,13 +584,13 @@ + https://github.com/processing/processing/issues/3359 + https://github.com/processing/processing/issues/3360 + The 'keytool' file is deleted by our appbundler. Add it back so that + Android signing works properly. (Not modifying our appbundler since + most of the time that appbundler is used, keytool isn't needed). + Also, because Ant's copy task does not retain file permissions on + Unix systems, we need to use instead --> diff --git a/build/shared/lib/theme.txt b/build/shared/lib/theme.txt index 2b9303217..f83724c47 100644 --- a/build/shared/lib/theme.txt +++ b/build/shared/lib/theme.txt @@ -9,7 +9,7 @@ status.edit.fgcolor = #000000 status.edit.bgcolor = #cc9900 status.font = processing.sans,plain,13 -# TABS +# HEADER TABS # Settings for the tab area at the top. header.text.font = processing.sans,bold,14 header.text.selected.color = #000000 @@ -19,16 +19,17 @@ header.gradient.top = #132638 header.gradient.bottom = #122535 header.tab.selected.color = #e0fffd header.tab.unselected.color = #2d4251 +header.tab.modified.color = #ef8115 -# LOWER TABS +# FOOTER TABS footer.text.font = processing.sans,bold,12 -footer.text.selected.color = #ffffff -footer.text.unselected.color = #000000 +footer.text.selected.color = #e0fffd +footer.text.unselected.color = #95adb0 footer.tab.arrow.color = #ffffff footer.gradient.top = #132638 footer.gradient.bottom = #122535 -footer.tab.selected.color = #3D5362 -footer.tab.unselected.color = #2d4251 +footer.tab.selected.color = #2d4251 +footer.tab.unselected.color = #1f3241 # updates orange #eb7f15 # CONSOLE diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 8410a8fd6..c928899e7 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -6368,7 +6368,9 @@ public class PApplet implements PConstants { if (platform == MACOSX && useNativeSelect != false) { FileDialog fileDialog = new FileDialog(parentFrame, prompt, FileDialog.LOAD); - fileDialog.setDirectory(defaultSelection.getAbsolutePath()); + if (defaultSelection != null) { + fileDialog.setDirectory(defaultSelection.getAbsolutePath()); + } System.setProperty("apple.awt.fileDialogForDirectories", "true"); fileDialog.setVisible(true); System.setProperty("apple.awt.fileDialogForDirectories", "false"); @@ -10020,6 +10022,9 @@ public class PApplet implements PConstants { // TODO IIRC this helped on Windows, but need to double check. System.setProperty("sun.awt.noerasebackground", "true"); + // Remove 60fps limit on the JavaFX "pulse" timer + System.setProperty("javafx.animation.fullspeed", "true"); + // Catch any HeadlessException to provide more useful feedback try { // Call validate() while resize events are in progress diff --git a/core/src/processing/javafx/PSurfaceFX.java b/core/src/processing/javafx/PSurfaceFX.java index 7e5e1c6b9..2c3ba1b87 100644 --- a/core/src/processing/javafx/PSurfaceFX.java +++ b/core/src/processing/javafx/PSurfaceFX.java @@ -22,22 +22,17 @@ package processing.javafx; -//import java.awt.event.FocusEvent; -//import java.awt.event.FocusListener; -//import java.awt.event.KeyListener; -//import java.awt.event.MouseListener; -//import java.awt.event.MouseMotionListener; -//import java.awt.event.MouseWheelEvent; -//import java.awt.event.MouseWheelListener; - import java.util.HashMap; import java.util.Map; -import javafx.animation.AnimationTimer; +import javafx.animation.Animation; +import javafx.animation.KeyFrame; +import javafx.animation.Timeline; import javafx.application.Application; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; +import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.event.EventType; import javafx.scene.Scene; @@ -49,6 +44,7 @@ import javafx.scene.input.ScrollEvent; import javafx.scene.layout.StackPane; import javafx.stage.Stage; import javafx.stage.WindowEvent; +import javafx.util.Duration; import processing.core.*; @@ -60,13 +56,32 @@ public class PSurfaceFX implements PSurface { Stage stage; Canvas canvas; - AnimationTimer timer; - + final Animation animation; public PSurfaceFX(PGraphicsFX2D graphics) { fx = graphics; canvas = new ResizableCanvas(); fx.context = canvas.getGraphicsContext2D(); + + // set up main drawing loop + KeyFrame keyFrame = new KeyFrame(Duration.millis(1000), + new EventHandler() { + public void handle(ActionEvent event) { + sketch.handleDraw(); + if (sketch.exitCalled()) { + Platform.exit(); // version for safe JavaFX shutdown + } + } + }); + animation = new Timeline(keyFrame); + animation.setCycleCount(Animation.INDEFINITE); + + // key frame has duration of 1 second, so the rate of the animation + // should be set to frames per second + + // setting rate to negative so that event fires at the start of + // the key frame and first frame is drawn immediately + animation.setRate(-60); } @@ -437,8 +452,9 @@ public class PSurfaceFX implements PSurface { public void setFrameRate(float fps) { - // TODO Auto-generated method stub - + // setting rate to negative so that event fires at the start of + // the key frame and first frame is drawn immediately + if (fps > 0) animation.setRate(-fps); } @@ -473,44 +489,28 @@ public class PSurfaceFX implements PSurface { public void startThread() { - if (timer == null) { - timer = new AnimationTimer() { - - @Override - public void handle(long now) { - //System.out.println("handle(" + now + ") calling handleDraw()"); - sketch.handleDraw(); - - if (sketch.exitCalled()) { - //sketch.exitActual(); // just calls System.exit() - Platform.exit(); // version for safe JavaFX shutdown - } - } - }; - timer.start(); - } + animation.play(); } public void pauseThread() { - // TODO Auto-generated method stub + animation.pause(); } public void resumeThread() { - // TODO Auto-generated method stub + animation.play(); } public boolean stopThread() { - // TODO Auto-generated method stub - return false; + animation.stop(); + return true; } public boolean isStopped() { - // TODO Auto-generated method stub - return false; + return animation.getStatus() == Animation.Status.STOPPED; } @@ -708,7 +708,12 @@ public class PSurfaceFX implements PSurface { long when = System.currentTimeMillis(); KeyCode kc = fxEvent.getCode(); // Are they f*ing serious? - char key = kc.impl_getChar().charAt(0); + char key; + if (et == KeyEvent.KEY_TYPED) { + key = fxEvent.getCharacter().charAt(0); + } else { + key = kc.impl_getChar().charAt(0); + } int keyCode = kc.impl_getCode(); sketch.postEvent(new processing.event.KeyEvent(fxEvent, when, action, modifiers, diff --git a/core/todo.txt b/core/todo.txt index 0fe001eaa..664460bc6 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,9 +1,24 @@ 0243 core (3.0b5) +X NullPointerException in selectFolder() on OS X +X https://github.com/processing/processing/issues/3661 + +cleaning +X How do images behave when pixelDensity(2) is set? +X https://github.com/processing/processing/issues/3364 +X retina sketches slow to start +X https://github.com/processing/processing/issues/2357 +X zero alpha values still a problem with retina renderer +X https://github.com/processing/processing/issues/2030 jakub X keyTyped() not firing with P2D and P3D X https://github.com/processing/processing/issues/3582 X https://github.com/processing/processing/pull/3652 +X rect() sizing in JavaFX +X https://github.com/processing/processing/pull/3656 +X FX - Proper sketch sizing +X https://github.com/processing/processing/pull/3658 +X implement frameRate() known issues @@ -60,7 +75,6 @@ _ https://github.com/processing/processing/issues/3274 _ getNative() in PImage problematic because it gives back a BufferedImage _ move loadImage() into PGraphics, with AWT version the default? _ or pass createImage() through to renderer? -_ implement frameRate() _ implement external messages (moving the window) _ implement PSurfaceFX.setIcon() _ javafx not supported with ARM (so we're screwed on raspberry pi) @@ -170,14 +184,8 @@ _ don't override the window icon w/ p5 logo if already set retina/hidpi -_ How do images behave when pixelDensity(2) is set? -_ https://github.com/processing/processing/issues/3364 _ no high-dpi support for core on Windows _ https://github.com/processing/processing/issues/2411 -_ retina sketches slow to start -_ https://github.com/processing/processing/issues/2357 -_ zero alpha values still a problem with retina renderer -_ https://github.com/processing/processing/issues/2030 decisions/misc diff --git a/java/src/processing/mode/java/JavaBuild.java b/java/src/processing/mode/java/JavaBuild.java index 7ae63a736..d4fee5d46 100644 --- a/java/src/processing/mode/java/JavaBuild.java +++ b/java/src/processing/mode/java/JavaBuild.java @@ -263,11 +263,14 @@ public class JavaBuild { if (sizeInfo != null && sizeInfo.hasSettings()) { // String sizeStatement = sizeInfo.getStatement(); for (String stmt : sizeInfo.getStatements()) { -// if (sizeStatement != null) { //System.out.format("size stmt is '%s'%n", sizeStatement); + // Don't remove newlines (and while you're at it, just keep spaces) + // https://github.com/processing/processing/issues/3654 + stmt = stmt.trim(); int index = bigCode.indexOf(stmt); if (index != -1) { bigCode.delete(index, index + stmt.length()); + System.out.println("code now " + bigCode); } else { // TODO remove once we hit final; but prevent an exception like in // https://github.com/processing/processing/issues/3531 @@ -1183,7 +1186,7 @@ public class JavaBuild { pw.close(); // attempt to code sign if the Xcode tools appear to be installed - if (Platform.isMacOS() && new File("/usr/bin/codesign_allocate").exists()) { + if (Platform.isMacOS() && isXcodeInstalled()) { if (embedJava) { ProcessHelper.ffs("codesign", "--force", "--sign", "-", jdkPath); } @@ -1331,6 +1334,23 @@ public class JavaBuild { } + static Boolean xcodeInstalled; + + static protected boolean isXcodeInstalled() { + if (xcodeInstalled == null) { + // http://stackoverflow.com/questions/15371925 + Process p = PApplet.launch("xcode-select", "-p"); + int result = -1; + try { + result = p.waitFor(); + } catch (InterruptedException e) { } + // returns 0 if installed, 2 if not (-1 if exception) + xcodeInstalled = (result == 0); + } + return xcodeInstalled; + } + + /** * Run the launch4j build.xml file through ant to create the exe. * Most of this code was lifted from Android mode. diff --git a/java/src/processing/mode/java/pdex/JavaTextArea.java b/java/src/processing/mode/java/pdex/JavaTextArea.java index 0461e34d1..f74df6dda 100644 --- a/java/src/processing/mode/java/pdex/JavaTextArea.java +++ b/java/src/processing/mode/java/pdex/JavaTextArea.java @@ -136,6 +136,7 @@ public class JavaTextArea extends JEditTextArea { gutterLineColor = mode.getColor("gutter.linecolor"); //, gutterLineColor); gutterPadding = mode.getInteger("gutter.padding"); breakpointMarker = mode.getString("breakpoint.marker"); //, breakpointMarker); +// breakpointMarker = "\u2666"; currentLineMarker = mode.getString("currentline.marker"); //, currentLineMarker); // TweakMode code diff --git a/todo.txt b/todo.txt index 69c5bb6a3..42fe2b63d 100644 --- a/todo.txt +++ b/todo.txt @@ -2,11 +2,52 @@ X processing-java isn't working in OS X 10.11 El Capitan X https://github.com/processing/processing/issues/3497 o probably have to add the script/Processing.app location to user's path +X line selected for errors is off by one or two +X https://github.com/processing/processing/issues/3654 -earlier +contribs +X Undo does not move to the correct location in the editor window +X https://github.com/processing/processing/issues/707 +X https://github.com/processing/processing/pull/3660 + +gsoc +X Foundation libraries disapear from CM after restart +X https://github.com/processing/processing/issues/3659 +X https://github.com/processing/processing/pull/3663 +X CM scrolls to bottom of window after updating the list +o https://github.com/processing/processing/issues/3248 +o https://github.com/processing/processing/pull/3328 +X no longer issue in the new release +X CM blue bar missing +X https://github.com/processing/processing/issues/3599 +X https://github.com/processing/processing/pull/3636 +X CM: Category dropdown alignment +X https://github.com/processing/processing/pull/3666 +_ https://github.com/processing/processing/issues/3644 + +cleaning X modify build to insert these after antlr run: X @SuppressWarnings({"unused", "cast"}) X or get the updated ANTLR, which likely would support it +o scrollable stack trace +o http://www.javalobby.org/java/forums/t19012.html + +cleaning/libraries +o different name for 'lib' folder because of libraries folder? +o avoid some confusion for when describing the libraries folder to users +X could have library developers update compatability note +X so they would need to test library and say "compatible with 0110" +X before it would automatically update or show as an update +o need an "install library" option to deal with urls.. +X need better platform designation setup for libs +X library installation should use the sketchbook folder, not the p5 folder +o actually enforce this, give users a warning about other libs +o versioning info +o http://java.sun.com/j2se/1.5.0/docs/guide/extensions/versioning.html +X changing the sketchbook folder will make libraries show up +o but it won't reload the library mapping table +o set DYLD_LIBRARY_PATH to include .dylib and other framework stuff +o java.library.path will only handle .jnilib stuff known issues @@ -32,15 +73,26 @@ _ http://www.oracle.com/us/technologies/java/locale-140624.html 3.0 final +_ prompt to install Xcode coming up on Export to Application +_ http://stackoverflow.com/questions/15371925/how-to-check-if-command-line-tools-is-installed +_ "xcode-select -p" returns 0 if they exist (and the dir) or 2 if they don't _ Contributions Manager UI design _ https://github.com/processing/processing/issues/3482 _ Ready to add contributed example packages? _ https://github.com/processing/processing/issues/2953 _ sketch modified externally with FAT32 volumes on OS X _ https://github.com/processing/processing/issues/3387 +_ also appearing with encrypted volumes? +_ also an un-ending loop caused by it +_ https://github.com/processing/processing/issues/3650 +_ add this to the preferences? gui +_ replace about screen (1x and 2x versions) +_ change 'alpha' to correct name +_ also change the revision in the "about processing" dialog +_ https://github.com/processing/processing/issues/3665 _ fix red in sidebar, the squiggly line beneath code _ Error/warning location visualisation not updating when editor resizes _ https://github.com/processing/processing/issues/3619 @@ -434,13 +486,11 @@ _ along with a "don't ask me later" _ use macosx dialogs for all of the editor stuff _ see about doing the same on windows, linux? _ the others seem to respond ok to the lucida grande since they use defaults -_ vista style dialogs -_ http://msdn.microsoft.com/en-us/library/bb328626.aspx -_ confirmation dialogs (save and don't save.. who'd a thunk it) -_ http://msdn.microsoft.com/en-us/library/aa511273.aspx -_ http://i.msdn.microsoft.com/Aa511273.Confirmations03(en-us,MSDN.10).png -_ scrollable stack trace -_ http://www.javalobby.org/java/forums/t19012.html +_ vista style dialogs +_ http://msdn.microsoft.com/en-us/library/bb328626.aspx +_ confirmation dialogs (save and don't save.. who'd a thunk it) +_ http://msdn.microsoft.com/en-us/library/aa511273.aspx +_ http://i.msdn.microsoft.com/Aa511273.Confirmations03(en-us,MSDN.10).png PDE / Compiler & Preprocessor @@ -483,8 +533,6 @@ _ https://github.com/processing/processing/issues/533 PDE / Editor -_ [help] Undo does not move to the correct location in the editor window -_ https://github.com/processing/processing/issues/707 _ clean up /tmp folders used during build _ https://github.com/processing/processing/issues/1896 _ 'recent' menu doesn't respect examples folder of other p5 versions @@ -564,9 +612,6 @@ _ exporting application copies .java files _ .java files are copied to the root folder as well as the source folder -PDE / Find & Replace - - PDE / Examples _ keep examples.zip in a zip file? (5000 files @ 30 MB instead of 15 MB zip) @@ -609,20 +654,16 @@ _ altho prolly only when it's actually different (md5hash it?) _ this seems to be causing a lot of trouble with recent releases _ (opengl changes and whatnot) _ jar files like the bad aiexport plugin will cause serious problems +_ https://github.com/processing/processing/issues/95 _ need to ignore processing.core classes showing up in other jar files _ tougher than it looks, because it all depends on what java wants to use _ i.e. even if not specified, the stuff will be in the classpath _ need to make classpath code be less promiscuous _ the order of adding libraries to classpath should be opposite _ the important local libraries should be first in cp, user contrib later -_ https://github.com/processing/processing/issues/95 -_ changing the sketchbook folder will make libraries show up -_ but it won't reload the library mapping table _ make sure there aren't library jar files named the same thing _ i.e. if one library has db.jar, then that's gonna kill another db.jar _ when the files are copied over -_ versioning info -_ http://java.sun.com/j2se/1.5.0/docs/guide/extensions/versioning.html _ java.ext.dirs for /System/Library/Java/Extensions _ http://java.sun.com/j2se/1.5.0/docs/guide/extensions/spec.html _ can set java.ext.dirs to something else @@ -631,17 +672,8 @@ _ native lib stuff, use native.txt in lib folder, then: _ String osName = System.getProperty("os.name"); _ String osArch = System.getProperty("os.arch"); _ http://stackoverflow.com/questions/1611357/how-to-make-a-jar-file-that-include-dll-files -_ need better platform designation setup for libs -_ library installation should use the sketchbook folder, not the p5 folder -_ actually enforce this, give users a warning about other libs -_ set DYLD_LIBRARY_PATH to include .dylib and other framework stuff -_ java.library.path will only handle .jnilib stuff _ need better error messages for broken api / library troubles _ e.g. ocd is broken in 0125 because of method signature changes -_ could have library developers update compatability note -_ so they would need to test library and say "compatible with 0110" -_ before it would automatically update or show as an update -_ need an "install library" option to deal with urls.. PDE / Manager @@ -686,9 +718,6 @@ _ font size for "Downloading" on progress bar is too large _ but changing the size breaks the vertical centering _ highlight color seems to be incorrect? _ after installing, the item in the manager list doesn't change color -_ scrolls to bottom of window after updating the list -_ https://github.com/processing/processing/issues/3248 -_ https://github.com/processing/processing/pull/3328 _ wheel mouse is super jumpy _ something about unit increment in ContributionListPanel _ arrow keys up/down move scroll bar, not selection @@ -850,8 +879,6 @@ _ about box _ bring up information about gpl, lgpl, and ibmpl _ jedit syntax is under mit license _ http://www.opensource.org/licenses/mit-license.php -_ different name for 'lib' folder because of libraries folder? -_ avoid some confusion for when describing the libraries folder to users _ add proper copyright and license information for all included projects _ https://github.com/processing/processing/issues/224 _ write up guidelines for modes