Merge remote-tracking branch 'upstream/master' into jdiMod

Rolling back
This commit is contained in:
Manindra Moharana
2013-02-18 03:22:11 +05:30
23 changed files with 806 additions and 727 deletions
+43 -34
View File
@@ -334,9 +334,7 @@ public class Base {
// removeDir(contrib.getFolder());
// }
// }
ContributionManager.checkDeletions(getSketchbookModesFolder());
ContributionManager.checkDeletions(getSketchbookToolsFolder());
ContributionManager.deleteFlagged();
buildCoreModes();
rebuildContribModes();
@@ -362,37 +360,15 @@ public class Base {
}
}
libraryManagerFrame = new ContributionManagerDialog("Library Manager",
new ContributionListing.Filter() {
public boolean matches(Contribution contrib) {
return contrib.getType() == ContributionType.LIBRARY;
// return contrib.getType() == Contribution.Type.LIBRARY
// || contrib.getType() == Contribution.Type.LIBRARY_COMPILATION;
}
});
toolManagerFrame = new ContributionManagerDialog("Tool Manager",
new ContributionListing.Filter() {
public boolean matches(Contribution contrib) {
return contrib.getType() == ContributionType.TOOL;
}
});
modeManagerFrame = new ContributionManagerDialog("Mode Manager",
new ContributionListing.Filter() {
public boolean matches(Contribution contrib) {
return contrib.getType() == ContributionType.MODE;
}
});
updateManagerFrame = new ContributionManagerDialog("Update Manager",
new ContributionListing.Filter() {
public boolean matches(Contribution contrib) {
if (contrib instanceof InstalledContribution) {
return ContributionListing.getInstance().hasUpdates(contrib);
}
return false;
}
});
libraryManagerFrame =
new ContributionManagerDialog(ContributionType.LIBRARY);
toolManagerFrame =
new ContributionManagerDialog(ContributionType.TOOL);
modeManagerFrame =
new ContributionManagerDialog(ContributionType.MODE);
updateManagerFrame =
new ContributionManagerDialog(null);
// Make sure ThinkDifferent has library examples too
nextMode.rebuildLibraryList();
@@ -2907,6 +2883,39 @@ public class Base {
}
}
}
static public void unzip(File zipFile, File dest) {
try {
FileInputStream fis = new FileInputStream(zipFile);
CheckedInputStream checksum = new CheckedInputStream(fis, new Adler32());
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(checksum));
ZipEntry next = null;
while ((next = zis.getNextEntry()) != null) {
File currentFile = new File(dest, next.getName());
if (next.isDirectory()) {
currentFile.mkdirs();
} else {
currentFile.createNewFile();
unzipEntry(zis, currentFile);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
static protected void unzipEntry(ZipInputStream zin, File f) throws IOException {
FileOutputStream out = new FileOutputStream(f);
byte[] b = new byte[512];
int len = 0;
while ((len = zin.read(b)) != -1) {
out.write(b, 0, len);
}
out.flush();
out.close();
}
static public void log(Object from, String message) {
+1 -1
View File
@@ -7,7 +7,7 @@ import processing.app.contrib.*;
import processing.core.*;
public class Library extends InstalledContribution {
public class Library extends LocalContribution {
static final String[] platformNames = PConstants.platformNames;
//protected File folder; // /path/to/shortname
@@ -29,110 +29,88 @@ import processing.app.Editor;
import processing.core.PApplet;
class AdvertisedContribution extends Contribution {
/**
* A class to hold information about a Contribution that can be downloaded.
*/
class AvailableContribution extends Contribution {
protected final ContributionType type; // Library, tool, etc.
protected final String link; // Direct link to download the file
// protected final String category; // "Sound"
// protected final String name; // "pdf" or "PDF Export"
// protected final String authorList; // [Ben Fry](http://benfry.com/)
// protected final String url; // http://processing.org
// protected final String sentence; // Write graphics to PDF files.
// protected final String paragraph; // <paragraph length description for site>
// protected final int version; // 102
// protected final String prettyVersion; // "1.0.2"
public AdvertisedContribution(ContributionType type, HashMap<String, String> exports) {
public AvailableContribution(ContributionType type, HashMap<String, String> params) {
this.type = type;
name = exports.get("name");
category = ContributionListing.getCategory(exports.get("category"));
authorList = exports.get("authorList");
url = exports.get("url");
sentence = exports.get("sentence");
paragraph = exports.get("paragraph");
int v = 0;
try {
v = Integer.parseInt(exports.get("version"));
} catch (NumberFormatException e) {
}
version = v;
prettyVersion = exports.get("prettyVersion");
this.link = exports.get("download");
this.link = params.get("download");
category = ContributionListing.getCategory(params.get("category"));
name = params.get("name");
authorList = params.get("authorList");
url = params.get("url");
sentence = params.get("sentence");
paragraph = params.get("paragraph");
version = PApplet.parseInt(params.get("version"), 0);
prettyVersion = params.get("prettyVersion");
}
/**
* @param contribArchive
* a zip file containing the library to install
* @param ad
* the advertised version of this library, if it was downloaded
* through the Contribution Manager. This is used to check the type
* of library being installed, and to replace the .properties file in
* the zip
* @param confirmReplace
* true to open a dialog asking the user to confirm removing/moving
* the library when a library by the same name already exists
* @return
*/
public InstalledContribution install(Editor editor, File contribArchive,
boolean confirmReplace,
ErrorWidget statusBar) {
public LocalContribution install(Editor editor, File contribArchive,
boolean confirmReplace, ErrorWidget status) {
// Unzip the file into the modes, tools, or libraries folder inside the
// sketchbook. Unzipping to /tmp is problematic because it may be on
// another file system, so move/rename operations will break.
File sketchbookContribFolder = type.getSketchbookContribFolder();
File sketchbookContribFolder = type.getSketchbookFolder();
File tempFolder = null;
try {
tempFolder =
Base.createTempFolder(type.toString(), "tmp", sketchbookContribFolder);
} catch (IOException e) {
statusBar.setErrorMessage("Could not create a temporary folder to install.");
status.setErrorMessage("Could not create a temporary folder to install.");
return null;
}
ContributionManager.unzip(contribArchive, tempFolder);
Base.unzip(contribArchive, tempFolder);
// Now go looking for a legit contrib inside what's been unpacked.
File contribFolder = null;
// Sometimes contrib authors place all their folders in the base directory
// of the .zip file instead of in single folder as the guidelines suggest.
if (InstalledContribution.isCandidate(tempFolder, type)) {
if (type.isCandidate(tempFolder)) {
contribFolder = tempFolder;
}
if (contribFolder == null) {
// Find the first legitimate looking folder in what we just unzipped
contribFolder = InstalledContribution.findCandidate(tempFolder, type);
contribFolder = type.findCandidate(tempFolder);
}
InstalledContribution installedContrib = null;
LocalContribution installedContrib = null;
if (contribFolder == null) {
statusBar.setErrorMessage("Could not find a " + type + " in the downloaded file.");
status.setErrorMessage("Could not find a " + type + " in the downloaded file.");
} else {
File propFile = new File(contribFolder, type + ".properties");
if (!writePropertiesFile(propFile)) {
// 1. contribFolder now has a legit contribution, load it to get info.
InstalledContribution newContrib =
ContributionManager.load(editor.getBase(), contribFolder, type);
LocalContribution newContrib =
type.load(editor.getBase(), contribFolder);
// 2. Check to make sure nothing has the same name already,
// backup old if needed, then move things into place and reload.
installedContrib =
newContrib.moveAndLoad(editor, confirmReplace, statusBar);
newContrib.moveAndLoad(editor, confirmReplace, status);
} else {
statusBar.setErrorMessage("Error overwriting .properties file.");
status.setErrorMessage("Error overwriting .properties file.");
}
}
@@ -142,7 +120,7 @@ class AdvertisedContribution extends Contribution {
}
return installedContrib;
}
public boolean isInstalled() {
return false;
@@ -153,43 +131,6 @@ class AdvertisedContribution extends Contribution {
return type;
}
// public String getTypeName() {
// return type.toString();
// }
//
// public String getCategory() {
// return category;
// }
//
// public String getName() {
// return name;
// }
//
// public String getAuthorList() {
// return authorList;
// }
//
// public String getUrl() {
// return url;
// }
//
// public String getSentence() {
// return sentence;
// }
//
// public String getParagraph() {
// return paragraph;
// }
//
// public int getVersion() {
// return version;
// }
//
// public String getPrettyVersion() {
// return prettyVersion;
// }
/**
* We overwrite the properties file with the curated version from the
@@ -202,7 +143,6 @@ class AdvertisedContribution extends Contribution {
public boolean writePropertiesFile(File propFile) {
try {
if (propFile.delete() && propFile.createNewFile() && propFile.setWritable(true)) {
//BufferedWriter bw = new BufferedWriter(new FileWriter(propFile));
PrintWriter writer = PApplet.createWriter(propFile);
writer.println("name=" + getName());
@@ -90,4 +90,19 @@ abstract public class Contribution {
abstract public boolean isInstalled();
/**
* Returns true if the type of contribution requires the PDE to restart
* when being added or removed.
*/
public boolean requiresRestart() {
return getType() == ContributionType.TOOL || getType() == ContributionType.MODE;
}
/** Overridden by InstalledContribution. */
boolean isDeletionFlagged() {
return false;
}
}
@@ -40,44 +40,38 @@ import java.net.*;
import processing.app.Base;
import processing.app.contrib.ContributionListing.ContributionChangeListener;
import processing.core.PApplet;
public class ContributionListPanel extends JPanel implements Scrollable, ContributionChangeListener {
static public final String DELETION_MESSAGE = "<i>This tool has "
+ "been flagged for deletion. Restart all instances of the editor to "
+ "finalize the removal process.</i>";
static public final String DELETION_MESSAGE =
"<i>This tool has been flagged for deletion. " +
"Restart Proessing to finalize the removal process.</i>";
static public final String INSTALL_FAILURE_TITLE = "Install Failed";
static public final String MALFORMED_URL_MESSAGE =
"The link fetched from Processing.org is invalid.\n"
+ "You can still intall this library manually by visiting\n"
+ "the library's website.";
"The link fetched from Processing.org is not valid.\n" +
"You can still install this library manually by visiting\n" +
"the library's website.";
ContributionManagerDialog contribManager;
TreeMap<Contribution, ContributionPanel> panelByContribution;
static private HyperlinkListener nullHyperlinkListener = new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent e) {
}
public void hyperlinkUpdate(HyperlinkEvent e) { }
};
protected ContributionPanel selectedPanel;
protected JPanel statusPlaceholder;
ContributionListing.Filter permaFilter;
ContributionListing contribListing;
public ContributionListPanel(ContributionManagerDialog libraryManager,
ContributionListing.Filter filter) {
super();
this.contribManager = libraryManager;
this.permaFilter = filter;
@@ -102,6 +96,7 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
statusPlaceholder.setVisible(false);
}
private void updatePanelOrdering() {
int row = 0;
for (Entry<Contribution, ContributionPanel> entry : panelByContribution.entrySet()) {
@@ -125,8 +120,8 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
add(statusPlaceholder, c);
}
public void contributionAdded(final Contribution contribution) {
if (permaFilter.matches(contribution)) {
SwingUtilities.invokeLater(new Runnable() {
@@ -141,10 +136,8 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
panelByContribution.put(contribution, newPanel);
}
if (newPanel != null) {
newPanel.setContribution(contribution);
add(newPanel);
updatePanelOrdering();
updateColors();
@@ -154,8 +147,9 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
}
}
public void contributionRemoved(final Contribution contribution) {
SwingUtilities.invokeLater(new Runnable() {
EventQueue.invokeLater(new Runnable() {
public void run() {
synchronized (panelByContribution) {
ContributionPanel panel = panelByContribution.get(contribution);
@@ -172,11 +166,11 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
});
}
public void contributionChanged(final Contribution oldContrib,
final Contribution newContrib) {
SwingUtilities.invokeLater(new Runnable() {
EventQueue.invokeLater(new Runnable() {
public void run() {
synchronized (panelByContribution) {
ContributionPanel panel = panelByContribution.get(oldContrib);
@@ -285,18 +279,21 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
}
}
static String toHex(Color c) {
StringBuilder hex = new StringBuilder();
hex.append(Integer.toString(c.getRed(), 16));
hex.append(Integer.toString(c.getGreen(), 16));
hex.append(Integer.toString(c.getBlue(), 16));
return hex.toString();
}
// static String toHex(Color c) {
// StringBuilder hex = new StringBuilder();
// hex.append(Integer.toString(c.getRed(), 16));
// hex.append(Integer.toString(c.getGreen(), 16));
// hex.append(Integer.toString(c.getBlue(), 16));
// return hex.toString();
// }
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
/**
* Amount to scroll to reveal a new page of items
*/
@@ -315,6 +312,7 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
return 0;
}
/**
* Amount to scroll to reveal the rest of something we are on or a new item
*/
@@ -409,45 +407,33 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
* Panel that expands and gives a brief overview of a library when clicked.
*/
private class ContributionPanel extends JPanel {
private static final int BUTTON_WIDTH = 100;
/** Should only be set through setContribution(), otherwise UI components
* will not be updated. */
Contribution contrib;
/**
* Should only be set through setContribution(),
* otherwise UI components will not be updated.
*/
private Contribution contrib;
boolean alreadySelected;
boolean enableHyperlinks;
HyperlinkListener conditionalHyperlinkOpener;
JTextPane headerText;
JTextPane descriptionText;
JTextPane updateNotificationLabel;
JButton updateButton;
JProgressBar installProgressBar;
JButton installRemoveButton;
JPopupMenu contextMenu;
JMenuItem openFolder;
private boolean alreadySelected;
private boolean enableHyperlinks;
private HyperlinkListener conditionalHyperlinkOpener;
private JTextPane headerText;
private JTextPane descriptionText;
private JTextPane updateNotificationLabel;
private JButton updateButton;
private JProgressBar installProgressBar;
private JButton installRemoveButton;
private JPopupMenu contextMenu;
private JMenuItem openFolder;
private HashSet<JTextPane> htmlPanes;
private ActionListener removeActionListener;
private ActionListener installActionListener;
private ActionListener undoActionListener;
private ContributionPanel() {
htmlPanes = new HashSet<JTextPane>();
enableHyperlinks = false;
@@ -467,33 +453,32 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
installActionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (contrib instanceof AdvertisedContribution) {
installContribution((AdvertisedContribution) contrib);
if (contrib instanceof AvailableContribution) {
installContribution((AvailableContribution) contrib);
}
}
};
undoActionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (contrib instanceof InstalledContribution) {
InstalledContribution installed = (InstalledContribution) contrib;
ContributionManager.unsetDeletionFlag(installed);
contribListing.replaceContribution(contrib, contrib);
if (contrib instanceof LocalContribution) {
LocalContribution installed = (LocalContribution) contrib;
installed.unsetDeletionFlag();
contribListing.replaceContribution(contrib, contrib); // ??
}
}
};
removeActionListener = new ActionListener() {
public void actionPerformed(ActionEvent arg) {
if (contrib.isInstalled() && contrib instanceof InstalledContribution) {
if (contrib.isInstalled() && contrib instanceof LocalContribution) {
updateButton.setEnabled(false);
installRemoveButton.setEnabled(false);
installProgressBar.setVisible(true);
ContributionManager.removeContribution(contribManager.editor,
(InstalledContribution) contrib,
new JProgressMonitor(installProgressBar) {
((LocalContribution) contrib).removeContribution(contribManager.editor,
new JProgressMonitor(installProgressBar) {
public void finishedAction() {
// Finished uninstalling the library
resetInstallProgressBarState();
@@ -509,8 +494,8 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
openFolder = new JMenuItem("Open Folder");
openFolder.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (contrib instanceof InstalledContribution) {
File folder = ((InstalledContribution) contrib).getFolder();
if (contrib instanceof LocalContribution) {
File folder = ((LocalContribution) contrib).getFolder();
Base.openFolder(folder);
}
}
@@ -533,9 +518,10 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
});
}
/**
* Create the widgets for the header panel which is visible when the library
* panel is not clicked
* Create the widgets for the header panel which is visible when the
* library panel is not clicked.
*/
private void addPaneComponents() {
setLayout(new GridBagLayout());
@@ -584,10 +570,7 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
descriptionPanel.add(descriptionText, dc);
}
int margin = 5;
if (Base.isMacOS()) {
margin = 15;
}
int margin = Base.isMacOS() ? 15 : 5;
{
GridBagConstraints dc = new GridBagConstraints();
dc.gridx = 1;
@@ -635,7 +618,7 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
public void actionPerformed(ActionEvent e) {
updateButton.setEnabled(false);
AdvertisedContribution ad = contribListing
AvailableContribution ad = contribListing
.getAdvertisedContribution(contrib);
String url = ad.link;
installContribution(ad, url);
@@ -732,7 +715,7 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
StringBuilder description = new StringBuilder();
description.append("<html><body>");
boolean isFlagged = ContributionManager.isDeletionFlagSet(contrib);
boolean isFlagged = contrib.isDeletionFlagged();
if (isFlagged) {
description.append(ContributionListPanel.DELETION_MESSAGE);
} else {
@@ -758,7 +741,7 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
versionText.append("To finish an update, reinstall this contribution after the restart.");
} else {
versionText.append("New version available!");
if (ContributionManager.requiresRestart(contrib)) {
if (contrib.requiresRestart()) {
versionText.append(" To update, first remove the current version.");
}
}
@@ -771,7 +754,7 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
}
updateButton.setEnabled(true);
if (contrib != null && !ContributionManager.requiresRestart(contrib)) {
if (contrib != null && !contrib.requiresRestart()) {
updateButton.setVisible(isSelected()
&& contribListing.hasUpdates(contrib));
}
@@ -802,7 +785,7 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
}
private void installContribution(AdvertisedContribution info) {
private void installContribution(AvailableContribution info) {
if (info.link == null) {
contribManager.statusBar.setErrorMessage("Your operating system "
+ "doesn't appear to be supported. You should visit the "
@@ -812,37 +795,37 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
}
}
private void installContribution(AdvertisedContribution ad, String url) {
private void installContribution(AvailableContribution ad, String url) {
installRemoveButton.setEnabled(false);
try {
URL downloadUrl = new URL(url);
installProgressBar.setVisible(true);
JProgressMonitor downloadProgress = new JProgressMonitor(installProgressBar) {
public void finishedAction() {
// Finished downloading library
}
};
JProgressMonitor installProgress = new JProgressMonitor(installProgressBar) {
public void finishedAction() {
// Finished installing library
resetInstallProgressBarState();
installRemoveButton.setEnabled(true);
if (isError()) {
contribManager.statusBar.setErrorMessage("An error occured when "
+ "downloading the contribution.");
}
}
};
ContributionManager.downloadAndInstall(contribManager.editor,
downloadUrl, ad,
new JProgressMonitor(installProgressBar) {
public void finishedAction() {
// Finished downloading library
}
},
new JProgressMonitor(installProgressBar) {
public void finishedAction() {
// Finished installing library
resetInstallProgressBarState();
installRemoveButton.setEnabled(true);
if (isError()) {
contribManager.statusBar.setErrorMessage("An error occured when "
+ "downloading the contribution.");
}
}
},
contribManager.statusBar
downloadUrl, ad,
downloadProgress, installProgress,
contribManager.statusBar
);
} catch (MalformedURLException e) {
@@ -898,7 +881,7 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
// hyperlink, it will be opened as the mouse is released.
enableHyperlinks = alreadySelected;
if (contrib != null && !ContributionManager.requiresRestart(contrib)) {
if (contrib != null && !contrib.requiresRestart()) {
updateButton.setVisible(isSelected()
&& contribListing.hasUpdates(contrib));
}
@@ -949,8 +932,8 @@ public class ContributionListPanel extends JPanel implements Scrollable, Contrib
if (doc instanceof HTMLDocument) {
HTMLDocument html = (HTMLDocument) doc;
StyleSheet stylesheet = html.getStyleSheet();
stylesheet.addRule("body {color:" + ContributionListPanel.toHex(fg) + ";}");
stylesheet.addRule("a {color:" + ContributionListPanel.toHex(fg) + "}");
stylesheet.addRule("body {color:" + PApplet.hex(fg.getRGB()).substring(2) + ";}");
stylesheet.addRule("a {color:" + PApplet.hex(fg.getRGB()).substring(2) + "}");
}
}
}
@@ -36,7 +36,7 @@ public class ContributionListing {
File listingFile;
ArrayList<ContributionChangeListener> listeners;
ArrayList<AdvertisedContribution> advertisedContributions;
ArrayList<AvailableContribution> advertisedContributions;
Map<String, List<Contribution>> librariesByCategory;
ArrayList<Contribution> allContributions;
boolean hasDownloadedLatestList;
@@ -53,7 +53,7 @@ public class ContributionListing {
private ContributionListing() {
listeners = new ArrayList<ContributionChangeListener>();
advertisedContributions = new ArrayList<AdvertisedContribution>();
advertisedContributions = new ArrayList<AvailableContribution>();
librariesByCategory = new HashMap<String, List<Contribution>>();
allContributions = new ArrayList<Contribution>();
downloadingListingLock = new ReentrantLock();
@@ -82,7 +82,6 @@ public class ContributionListing {
for (Contribution contribution : advertisedContributions) {
addContribution(contribution);
}
Collections.sort(allContributions, contribComparator);
}
@@ -170,8 +169,8 @@ public class ContributionListing {
}
public AdvertisedContribution getAdvertisedContribution(Contribution info) {
for (AdvertisedContribution advertised : advertisedContributions) {
public AvailableContribution getAdvertisedContribution(Contribution info) {
for (AvailableContribution advertised : advertisedContributions) {
if (advertised.getType() == info.getType() &&
advertised.getName().equals(info.getName())) {
return advertised;
@@ -487,11 +486,11 @@ public class ContributionListing {
}
public ArrayList<AdvertisedContribution> parseContribList(File f) {
ArrayList<AdvertisedContribution> outgoing = new ArrayList<AdvertisedContribution>();
ArrayList<AvailableContribution> parseContribList(File file) {
ArrayList<AvailableContribution> outgoing = new ArrayList<AvailableContribution>();
if (f != null && f.exists()) {
String lines[] = PApplet.loadStrings(f);
if (file != null && file.exists()) {
String lines[] = PApplet.loadStrings(file);
int start = 0;
while (start < lines.length) {
@@ -516,9 +515,9 @@ public class ContributionListing {
System.arraycopy(lines, start, contribLines, 0, length);
HashMap<String,String> contribParams = new HashMap<String,String>();
Base.readSettings(f.getName(), contribLines, contribParams);
Base.readSettings(file.getName(), contribLines, contribParams);
outgoing.add(new AdvertisedContribution(contribType, contribParams));
outgoing.add(new AvailableContribution(contribType, contribParams));
start = end + 1;
// } else {
// start++;
@@ -534,10 +533,34 @@ public class ContributionListing {
}
public static interface Filter {
static interface Filter {
boolean matches(Contribution contrib);
}
/**
* Create a filter for a specific contribution type.
* @param type The type, or null for a generic update checker.
*/
static Filter createFilter(final ContributionType type) {
if (type == null) {
return new Filter() {
public boolean matches(Contribution contrib) {
if (contrib instanceof LocalContribution) {
return ContributionListing.getInstance().hasUpdates(contrib);
}
return false;
}
};
} else {
return new Filter() {
public boolean matches(Contribution contrib) {
return contrib.getType() == type;
}
};
}
}
static Comparator<Contribution> contribComparator = new Comparator<Contribution>() {
public int compare(Contribution o1, Contribution o2) {
@@ -23,14 +23,9 @@ package processing.app.contrib;
import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.*;
import processing.app.Base;
import processing.app.Editor;
import processing.app.Library;
import processing.app.Preferences;
interface ErrorWidget {
@@ -39,7 +34,6 @@ interface ErrorWidget {
public class ContributionManager {
static public final String DELETION_FLAG = "flagged_for_deletion";
static public final ContributionListing contribListing;
static {
@@ -47,65 +41,6 @@ public class ContributionManager {
}
/**
* Non-blocking call to remove a contribution in a new thread.
*/
static public void removeContribution(final Editor editor,
final InstalledContribution contribution,
final ProgressMonitor pm,
final ErrorWidget statusBar) {
if (contribution != null) {
final ProgressMonitor progressMonitor = (pm != null) ? pm : new NullProgressMonitor();
new Thread(new Runnable() {
public void run() {
progressMonitor.startTask("Removing", ProgressMonitor.UNKNOWN);
boolean doBackup = Preferences.getBoolean("contribution.backup.on_remove");
if (ContributionManager.requiresRestart(contribution)) {
if (!doBackup || (doBackup && backupContribution(editor, contribution, false, statusBar))) {
if (ContributionManager.setDeletionFlag(contribution)) {
contribListing.replaceContribution(contribution, contribution);
}
}
} else {
boolean success = false;
if (doBackup) {
success = backupContribution(editor, contribution, true, statusBar);
} else {
Base.removeDir(contribution.getFolder());
success = !contribution.getFolder().exists();
}
if (success) {
Contribution advertisedVersion =
contribListing.getAdvertisedContribution(contribution);
if (advertisedVersion == null) {
contribListing.removeContribution(contribution);
} else {
contribListing.replaceContribution(contribution,
advertisedVersion);
}
} else {
// There was a failure backing up the folder
if (doBackup) {
} else {
statusBar.setErrorMessage("Could not delete the contribution's files");
}
}
}
refreshInstalled(editor);
progressMonitor.finished();
}
}).start();
}
}
/**
* Non-blocking call to download and install a contribution in a new thread.
*
@@ -117,12 +52,12 @@ public class ContributionManager {
* old version of a contribution that is being updated). Must not be
* null.
*/
static public void downloadAndInstall(final Editor editor,
final URL url,
final AdvertisedContribution ad,
final JProgressMonitor downloadProgress,
final JProgressMonitor installProgress,
final ErrorWidget statusBar) {
static void downloadAndInstall(final Editor editor,
final URL url,
final AvailableContribution ad,
final JProgressMonitor downloadProgress,
final JProgressMonitor installProgress,
final ErrorWidget statusBar) {
new Thread(new Runnable() {
public void run() {
@@ -137,7 +72,7 @@ public class ContributionManager {
if (!downloadProgress.isCanceled() && !downloadProgress.isError()) {
installProgress.startTask("Installing...", ProgressMonitor.UNKNOWN);
InstalledContribution contribution =
LocalContribution contribution =
ad.install(editor, contribZip, false, statusBar);
if (contribution != null) {
@@ -200,39 +135,39 @@ public class ContributionManager {
// }
static InstalledContribution load(Base base, File folder, ContributionType type) {
switch (type) {
case LIBRARY:
return new Library(folder);
// case LIBRARY_COMPILATION:
// return LibraryCompilation.create(folder);
case TOOL:
return ToolContribution.load(folder);
case MODE:
return ModeContribution.load(base, folder);
}
return null;
}
static ArrayList<InstalledContribution> listContributions(ContributionType type, Editor editor) {
ArrayList<InstalledContribution> contribs = new ArrayList<InstalledContribution>();
switch (type) {
case LIBRARY:
contribs.addAll(editor.getMode().contribLibraries);
break;
// case LIBRARY_COMPILATION:
// contribs.addAll(LibraryCompilation.list(editor.getMode().contribLibraries));
// static InstalledContribution load(Base base, File folder, ContributionType type) {
// switch (type) {
// case LIBRARY:
// return new Library(folder);
//// case LIBRARY_COMPILATION:
//// return LibraryCompilation.create(folder);
// case TOOL:
// return ToolContribution.load(folder);
// case MODE:
// return ModeContribution.load(base, folder);
// }
// return null;
// }
//
//
// static ArrayList<InstalledContribution> listContributions(ContributionType type, Editor editor) {
// ArrayList<InstalledContribution> contribs = new ArrayList<InstalledContribution>();
// switch (type) {
// case LIBRARY:
// contribs.addAll(editor.getMode().contribLibraries);
// break;
case TOOL:
contribs.addAll(editor.contribTools);
break;
case MODE:
contribs.addAll(editor.getBase().getModeContribs());
break;
}
return contribs;
}
//// case LIBRARY_COMPILATION:
//// contribs.addAll(LibraryCompilation.list(editor.getMode().contribLibraries));
//// break;
// case TOOL:
// contribs.addAll(editor.contribTools);
// break;
// case MODE:
// contribs.addAll(editor.getBase().getModeContribs());
// break;
// }
// return contribs;
// }
// static void initialize(InstalledContribution contribution, Base base) throws Exception {
@@ -461,86 +396,31 @@ public class ContributionManager {
*/
/**
* Moves the given contribution to a backup folder.
* @param doDeleteOriginal
* true if the file should be moved to the directory, false if it
* should instead be copied, leaving the original in place
*/
static public boolean backupContribution(Editor editor,
InstalledContribution contribution,
boolean doDeleteOriginal,
ErrorWidget statusBar) {
File backupFolder = null;
switch (contribution.getType()) {
case LIBRARY:
// case LIBRARY_COMPILATION:
backupFolder = createLibraryBackupFolder(editor, statusBar);
break;
case MODE:
break;
case TOOL:
backupFolder = createToolBackupFolder(editor, statusBar);
break;
}
if (backupFolder == null) return false;
String libFolderName = contribution.getFolder().getName();
String prefix = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
final String backupName = prefix + "_" + libFolderName;
File backupSubFolder = ContributionManager.getUniqueName(backupFolder, backupName);
// try {
// FileUtils.moveDirectory(lib.folder, backupFolderForLib);
// return true;
boolean success = false;
if (doDeleteOriginal) {
success = contribution.getFolder().renameTo(backupSubFolder);
} else {
try {
Base.copyDir(contribution.getFolder(), backupSubFolder);
success = true;
} catch (IOException e) {
}
}
// } catch (IOException e) {
if (!success) {
statusBar.setErrorMessage("Could not move contribution to backup folder.");
}
return success;
}
static public File createLibraryBackupFolder(Editor editor, ErrorWidget logger) {
File libraryBackupFolder = new File(Base.getSketchbookLibrariesFolder(), "old");
return createBackupFolder(libraryBackupFolder, logger,
"Could not create backup folder for library.");
}
static public File createToolBackupFolder(Editor editor, ErrorWidget logger) {
File libraryBackupFolder = new File(Base.getSketchbookToolsFolder(), "old");
return createBackupFolder(libraryBackupFolder, logger,
"Could not create backup folder for tool.");
}
static private File createBackupFolder(File backupFolder,
ErrorWidget logger,
String errorMessage) {
if (!backupFolder.exists() || !backupFolder.isDirectory()) {
if (!backupFolder.mkdirs()) {
logger.setErrorMessage(errorMessage);
return null;
}
}
return backupFolder;
}
// static public File createLibraryBackupFolder(Editor editor, ErrorWidget logger) {
// File libraryBackupFolder = new File(Base.getSketchbookLibrariesFolder(), "old");
// return createBackupFolder(libraryBackupFolder, logger,
// "Could not create backup folder for library.");
// }
//
//
// static public File createToolBackupFolder(Editor editor, ErrorWidget logger) {
// File libraryBackupFolder = new File(Base.getSketchbookToolsFolder(), "old");
// return createBackupFolder(libraryBackupFolder, logger,
// "Could not create backup folder for tool.");
// }
//
//
// static private File createBackupFolder(File backupFolder,
// ErrorWidget logger,
// String errorMessage) {
// if (!backupFolder.exists() || !backupFolder.isDirectory()) {
// if (!backupFolder.mkdirs()) {
// logger.setErrorMessage(errorMessage);
// return null;
// }
// }
// return backupFolder;
// }
/**
@@ -640,83 +520,20 @@ public class ContributionManager {
return fileName;
}
public static void unzip(File zipFile, File dest) {
try {
FileInputStream fis = new FileInputStream(zipFile);
CheckedInputStream checksum = new CheckedInputStream(fis, new Adler32());
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(checksum));
ZipEntry next = null;
while ((next = zis.getNextEntry()) != null) {
File currentFile = new File(dest, next.getName());
if (next.isDirectory()) {
currentFile.mkdirs();
} else {
currentFile.createNewFile();
ContributionManager.unzipEntry(zis, currentFile);
}
}
} catch (Exception e) {
e.printStackTrace();
}
static public void deleteFlagged() {
deleteFlagged(Base.getSketchbookLibrariesFolder());
deleteFlagged(Base.getSketchbookModesFolder());
deleteFlagged(Base.getSketchbookToolsFolder());
}
private static void unzipEntry(ZipInputStream zin, File f) throws IOException {
FileOutputStream out = new FileOutputStream(f);
byte[] b = new byte[512];
int len = 0;
while ((len = zin.read(b)) != -1) {
out.write(b, 0, len);
}
out.flush();
out.close();
}
/** Returns true if the type of contribution requires the PDE to restart
* when being removed. */
static public boolean requiresRestart(Contribution contrib) {
return contrib.getType() == ContributionType.TOOL || contrib.getType() == ContributionType.MODE;
}
static public boolean setDeletionFlag(InstalledContribution contrib) {
// Only returns false if the file already exists, so we can
// ignore the return value.
try {
new File(contrib.getFolder(), DELETION_FLAG).createNewFile();
return true;
} catch (IOException e) {
return false;
}
}
static public boolean unsetDeletionFlag(InstalledContribution contrib) {
return new File(contrib.getFolder(), DELETION_FLAG).delete();
}
static public boolean isDeletionFlagSet(Contribution contrib) {
if (contrib instanceof InstalledContribution) {
InstalledContribution installed = (InstalledContribution) contrib;
return isDeletionFlagSet(installed.getFolder());
}
return false;
}
static public boolean isDeletionFlagSet(File folder) {
return new File(folder, DELETION_FLAG).exists();
}
static public void checkDeletions(File root) {
static private void deleteFlagged(File root) {
File[] markedForDeletion = root.listFiles(new FileFilter() {
public boolean accept(File folder) {
return (folder.isDirectory() && isDeletionFlagSet(folder));
return (folder.isDirectory() &&
LocalContribution.isDeletionFlagged(folder));
}
});
for (File folder : markedForDeletion) {
@@ -39,12 +39,11 @@ import processing.app.contrib.ContributionListing.Filter;
public class ContributionManagerDialog {
static final String ANY_CATEGORY = "All";
JFrame dialog;
String title;
Filter permaFilter;
Filter filter;
JComboBox categoryChooser;
JScrollPane scrollPane;
ContributionListPanel contributionListPanel;
@@ -57,14 +56,14 @@ public class ContributionManagerDialog {
ContributionListing contribListing;
public ContributionManagerDialog(String title,
ContributionListing.Filter filter) {
this.title = title;
this.permaFilter = filter;
public ContributionManagerDialog(ContributionType type) {
if (type == null) {
title = "Update Manager";
} else {
title = type.getTitle() + " Manager";
}
filter = ContributionListing.createFilter(type);
contribListing = ContributionListing.getInstance();
contributionListPanel = new ContributionListPanel(this, filter);
contribListing.addContributionListener(contributionListPanel);
}
@@ -116,10 +115,10 @@ public class ContributionManagerDialog {
}
});
}
updateContributionListing();
}
/**
* Close the window after an OK or Cancel.
*/
@@ -127,6 +126,7 @@ public class ContributionManagerDialog {
dialog.dispose();
editor = null;
}
/** Creates and arranges the Swing components in the dialog. */
private void createComponents() {
@@ -243,12 +243,13 @@ public class ContributionManagerDialog {
dialog.setMinimumSize(new Dimension(450, 400));
}
private void updateCategoryChooser() {
if (categoryChooser != null) {
ArrayList<String> categories;
categoryChooser.removeAllItems();
categories = new ArrayList<String>(contribListing.getCategories(permaFilter));
categories = new ArrayList<String>(contribListing.getCategories(filter));
// for (int i = 0; i < categories.size(); i++) {
// System.out.println(i + " category: " + categories.get(i));
// }
@@ -262,6 +263,7 @@ public class ContributionManagerDialog {
}
}
private void registerDisposeListeners() {
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
@@ -289,19 +291,17 @@ public class ContributionManagerDialog {
});
}
public void filterLibraries(String category, List<String> filters) {
List<Contribution> filteredLibraries = contribListing
.getFilteredLibraryList(category, filters);
protected void filterLibraries(String category, List<String> filters) {
List<Contribution> filteredLibraries =
contribListing.getFilteredLibraryList(category, filters);
contributionListPanel.filterLibraries(filteredLibraries);
}
protected void updateContributionListing() {
if (editor == null)
return;
ArrayList<Library> libraries = new ArrayList<Library>(editor.getMode().contribLibraries);
if (editor != null) {
ArrayList<Library> libraries = new ArrayList<Library>(editor.getMode().contribLibraries);
// ArrayList<LibraryCompilation> compilations = LibraryCompilation.list(libraries);
//
// // Remove libraries from the list that are part of a compilations
@@ -315,65 +315,63 @@ public class ContributionManagerDialog {
// }
// }
ArrayList<Contribution> contributions = new ArrayList<Contribution>();
contributions.addAll(editor.contribTools);
contributions.addAll(libraries);
ArrayList<Contribution> contributions = new ArrayList<Contribution>();
contributions.addAll(editor.contribTools);
contributions.addAll(libraries);
// contributions.addAll(compilations);
contribListing.updateInstalledList(contributions);
contribListing.updateInstalledList(contributions);
}
}
public void setFilterText(String filter) {
protected void setFilterText(String filter) {
if (filter == null || filter.isEmpty()) {
filterField.setText("");
filterField.isShowingHint = true;
filterField.showingHint = true;
} else {
filterField.setText(filter);
filterField.isShowingHint = false;
filterField.showingHint = false;
}
filterField.applyFilter();
}
protected JPanel getPlaceholder() {
return contributionListPanel.statusPlaceholder;
}
class FilterField extends JTextField {
final static String filterHint = "Filter your search...";
boolean isShowingHint;
boolean showingHint;
List<String> filters;
public FilterField () {
super(filterHint);
isShowingHint = true;
showingHint = true;
filters = new ArrayList<String>();
updateStyle();
addFocusListener(new FocusListener() {
public void focusLost(FocusEvent focusEvent) {
if (filterField.getText().isEmpty()) {
isShowingHint = true;
showingHint = true;
}
updateStyle();
}
public void focusGained(FocusEvent focusEvent) {
if (isShowingHint) {
isShowingHint = false;
if (showingHint) {
showingHint = false;
filterField.setText("");
}
updateStyle();
}
});
getDocument().addDocumentListener(new DocumentListener() {
public void removeUpdate(DocumentEvent e) {
applyFilter();
}
@@ -399,11 +397,11 @@ public class ContributionManagerDialog {
}
public String getFilterText() {
return isShowingHint ? "" : getText();
return showingHint ? "" : getText();
}
public void updateStyle() {
if (isShowingHint) {
if (showingHint) {
setText(filterHint);
// setForeground(UIManager.getColor("TextField.light")); // too light
@@ -416,12 +414,13 @@ public class ContributionManagerDialog {
}
}
public boolean hasAlreadyBeenOpened() {
return dialog != null;
}
class StatusPanel extends JPanel implements ErrorWidget {
String errorMessage;
StatusPanel() {
@@ -457,27 +456,22 @@ public class ContributionManagerDialog {
errorMessage = message;
setVisible(true);
JPanel placeholder = ContributionManagerDialog.this.contributionListPanel.statusPlaceholder;
JPanel placeholder = getPlaceholder();
Dimension d = getPreferredSize();
if (Base.isWindows()) {
d.height += 5;
placeholder.setPreferredSize(d);
}
placeholder.setVisible(true);
// Rectangle rect = scrollPane.getViewport().getViewRect();
// rect.x += d.height;
// scrollPane.getViewport().scrollRectToVisible(rect);
}
void clearErrorMessage() {
errorMessage = null;
repaint();
ContributionManagerDialog.this.contributionListPanel.statusPlaceholder
.setVisible(false);
getPlaceholder().setVisible(false);
}
}
}
}
@@ -22,42 +22,53 @@
package processing.app.contrib;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import processing.app.Base;
import processing.app.Editor;
import processing.app.Library;
public enum ContributionType {
// LIBRARY, LIBRARY_COMPILATION, TOOL, MODE;
LIBRARY, TOOL, MODE;
LIBRARY, TOOL, MODE;
public String toString() {
switch (this) {
case LIBRARY:
return "library";
public String toString() {
switch (this) {
case LIBRARY:
return "library";
// case LIBRARY_COMPILATION:
// return "compilation";
case TOOL:
return "tool";
case MODE:
return "mode";
}
return null; // should be unreachable
};
case TOOL:
return "tool";
case MODE:
return "mode";
}
return null; // should be unreachable
};
/** Return Mode for mode, Tool for tool, etc. */
public String getTitle() {
String s = toString();
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
}
public String getFolderName() {
switch (this) {
case LIBRARY:
return "libraries";
public String getFolderName() {
switch (this) {
case LIBRARY:
return "libraries";
// case LIBRARY_COMPILATION:
// return "libraries";
case TOOL:
return "tools";
case MODE:
return "modes";
}
return null; // should be unreachable
case TOOL:
return "tools";
case MODE:
return "modes";
}
return null; // should be unreachable
}
// public String getPropertiesName() {
@@ -65,39 +76,117 @@ public enum ContributionType {
// }
static public ContributionType fromName(String s) {
if (s != null) {
if ("library".equals(s.toLowerCase())) {
return LIBRARY;
}
static public ContributionType fromName(String s) {
if (s != null) {
if ("library".equals(s.toLowerCase())) {
return LIBRARY;
}
// if ("compilation".equals(s.toLowerCase())) {
// return LIBRARY_COMPILATION;
// }
if ("tool".equals(s.toLowerCase())) {
return TOOL;
}
if ("mode".equals(s.toLowerCase())) {
return MODE;
}
if ("tool".equals(s.toLowerCase())) {
return TOOL;
}
return null;
}
public File getSketchbookContribFolder() {
switch (this) {
case LIBRARY:
return Base.getSketchbookLibrariesFolder();
case TOOL:
return Base.getSketchbookToolsFolder();
case MODE:
return Base.getSketchbookModesFolder();
if ("mode".equals(s.toLowerCase())) {
return MODE;
}
return null;
}
return null;
}
// static public boolean validName(String s) {
// return "library".equals(s) || "tool".equals(s) || "mode".equals(s);
// }
}
public File getSketchbookFolder() {
switch (this) {
case LIBRARY:
return Base.getSketchbookLibrariesFolder();
case TOOL:
return Base.getSketchbookToolsFolder();
case MODE:
return Base.getSketchbookModesFolder();
}
return null;
}
boolean isCandidate(File potential) {
return (potential.isDirectory() &&
new File(potential, getFolderName()).exists());
}
/**
* Return a list of directories that have the necessary subfolder for this
* contribution type. For instance, a list of folders that have a 'mode'
* subfolder if this is a ModeContribution.
*/
File[] listCandidates(File folder) {
return folder.listFiles(new FileFilter() {
public boolean accept(File potential) {
return isCandidate(potential);
}
});
}
/**
* Return the first directory that has the necessary subfolder for this
* contribution type. For instance, the first folder that has a 'mode'
* subfolder if this is a ModeContribution.
*/
File findCandidate(File folder) {
File[] folders = listCandidates(folder);
if (folders.length == 0) {
return null;
} else if (folders.length > 1) {
Base.log("More than one " + toString() + " found inside " + folder.getAbsolutePath());
}
return folders[0];
}
LocalContribution load(Base base, File folder) {
switch (this) {
case LIBRARY:
return new Library(folder);
case TOOL:
return ToolContribution.load(folder);
case MODE:
return ModeContribution.load(base, folder);
}
return null;
}
ArrayList<LocalContribution> listContributions(Editor editor) {
ArrayList<LocalContribution> contribs = new ArrayList<LocalContribution>();
switch (this) {
case LIBRARY:
contribs.addAll(editor.getMode().contribLibraries);
break;
case TOOL:
contribs.addAll(editor.contribTools);
break;
case MODE:
contribs.addAll(editor.getBase().getModeContribs());
break;
}
return contribs;
}
File createBackupFolder(ErrorWidget status) {
File backupFolder = new File(getSketchbookFolder(), "old");
if (!backupFolder.isDirectory()) {
status.setErrorMessage("Remove the file named \"old\" from the " +
getFolderName() + " folder in the sketchbook.");
return null;
}
if (!backupFolder.exists() && !backupFolder.mkdirs()) {
status.setErrorMessage("Could not create a " + toString() + " backup folder.");
return null;
}
return backupFolder;
}
}
@@ -24,6 +24,7 @@ package processing.app.contrib;
import java.io.*;
import java.net.URL;
import java.net.URLClassLoader;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.*;
@@ -32,27 +33,21 @@ import javax.swing.JOptionPane;
import processing.app.*;
public abstract class InstalledContribution extends Contribution {
//public abstract class InstalledContribution implements Contribution {
// protected String name; // "pdf" or "PDF Export"
// protected String category; // "Sound"
// protected String authorList; // Ben Fry
// protected String url; // http://processing.org
// protected String sentence; // Write graphics to PDF files.
// protected String paragraph; // <paragraph length description for site>
// protected int version; // 102
// protected String prettyVersion; // "1.0.2"
protected String id; // 1
protected int latestVersion; // 103
/**
* A contribution that has been downloaded to the disk, and may or may not
* be installed.
*/
public abstract class LocalContribution extends Contribution {
static public final String DELETION_FLAG = "flagged_for_deletion";
protected String id; // 1
protected int latestVersion; // 103
protected File folder;
protected HashMap<String, String> properties;
protected ClassLoader loader;
public InstalledContribution(File folder) {
public LocalContribution(File folder) {
this.folder = folder;
// required for contributed modes, but not for built-in core modes
@@ -149,62 +144,62 @@ public abstract class InstalledContribution extends Contribution {
*/
static protected boolean isCandidate(File potential, final ContributionType type) {
return (potential.isDirectory() &&
new File(potential, type.getFolderName()).exists());
}
// static protected boolean isCandidate(File potential, final ContributionType type) {
// return (potential.isDirectory() &&
// new File(potential, type.getFolderName()).exists());
// }
//
//
// /**
// * Return a list of directories that have the necessary subfolder for this
// * contribution type. For instance, a list of folders that have a 'mode'
// * subfolder if this is a ModeContribution.
// */
// static protected File[] listCandidates(File folder, final ContributionType type) {
// return folder.listFiles(new FileFilter() {
// public boolean accept(File potential) {
// return isCandidate(potential, type);
// }
// });
// }
//
//
// /**
// * Return the first directory that has the necessary subfolder for this
// * contribution type. For instance, the first folder that has a 'mode'
// * subfolder if this is a ModeContribution.
// */
// static protected File findCandidate(File folder, final ContributionType type) {
// File[] folders = listCandidates(folder, type);
//
// if (folders.length == 0) {
// return null;
//
// } else if (folders.length > 1) {
// Base.log("More than one " + type.toString() + " found inside " + folder.getAbsolutePath());
// }
// return folders[0];
// }
/**
* Return a list of directories that have the necessary subfolder for this
* contribution type. For instance, a list of folders that have a 'mode'
* subfolder if this is a ModeContribution.
*/
static protected File[] listCandidates(File folder, final ContributionType type) {
return folder.listFiles(new FileFilter() {
public boolean accept(File potential) {
return isCandidate(potential, type);
}
});
}
/**
* Return the first directory that has the necessary subfolder for this
* contribution type. For instance, the first folder that has a 'mode'
* subfolder if this is a ModeContribution.
*/
static protected File findCandidate(File folder, final ContributionType type) {
File[] folders = listCandidates(folder, type);
if (folders.length == 0) {
return null;
} else if (folders.length > 1) {
Base.log("More than one " + type.toString() + " found inside " + folder.getAbsolutePath());
}
return folders[0];
}
InstalledContribution moveAndLoad(Editor editor,
LocalContribution moveAndLoad(Editor editor,
boolean confirmReplace,
ErrorWidget statusBar) {
ArrayList<InstalledContribution> oldContribs =
ContributionManager.listContributions(getType(), editor);
ArrayList<LocalContribution> oldContribs =
getType().listContributions(editor);
String contribFolderName = getFolder().getName();
File contribTypeFolder = getType().getSketchbookContribFolder();
File contribTypeFolder = getType().getSketchbookFolder();
File contribFolder = new File(contribTypeFolder, contribFolderName);
for (InstalledContribution oldContrib : oldContribs) {
for (LocalContribution oldContrib : oldContribs) {
if ((oldContrib.getFolder().exists() && oldContrib.getFolder().equals(contribFolder)) ||
(oldContrib.getId() != null && oldContrib.getId().equals(getId()))) {
if (ContributionManager.requiresRestart(oldContrib)) {
if (oldContrib.requiresRestart()) {
// XXX: We can't replace stuff, soooooo.... do something different
if (!ContributionManager.backupContribution(editor, oldContrib, false, statusBar)) {
if (!oldContrib.backup(editor, false, statusBar)) {
return null;
}
} else {
@@ -218,7 +213,7 @@ public abstract class InstalledContribution extends Contribution {
"has been found in your sketchbook. Clicking “Yes”<br>"+
"will move the existing library to a backup folder<br>" +
" in <i>libraries/old</i> before replacing it.");
if (result != JOptionPane.YES_OPTION || !ContributionManager.backupContribution(editor, oldContrib, true, statusBar)) {
if (result != JOptionPane.YES_OPTION || !oldContrib.backup(editor, true, statusBar)) {
return null;
}
} else {
@@ -233,7 +228,7 @@ public abstract class InstalledContribution extends Contribution {
}
}
} else {
if ((doBackup && !ContributionManager.backupContribution(editor, oldContrib, true, statusBar)) ||
if ((doBackup && !oldContrib.backup(editor, true, statusBar)) ||
(!doBackup && !oldContrib.getFolder().delete())) {
return null;
}
@@ -252,10 +247,106 @@ public abstract class InstalledContribution extends Contribution {
" \"" + getName() + "\" to the sketchbook.");
return null;
}
return ContributionManager.load(editor.getBase(), contribFolder, getType());
return getType().load(editor.getBase(), contribFolder);
}
/**
* Moves the given contribution to a backup folder.
* @param deleteOriginal
* true if the file should be moved to the directory, false if it
* should instead be copied, leaving the original in place
*/
boolean backup(Editor editor, boolean deleteOriginal, ErrorWidget status) {
boolean success = false;
File backupFolder = getType().createBackupFolder(status);
if (backupFolder != null) {
String libFolderName = getFolder().getName();
String prefix = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
final String backupName = prefix + "_" + libFolderName;
File backupSubFolder = ContributionManager.getUniqueName(backupFolder, backupName);
if (deleteOriginal) {
success = getFolder().renameTo(backupSubFolder);
} else {
try {
Base.copyDir(getFolder(), backupSubFolder);
success = true;
} catch (IOException e) { }
}
if (!success) {
status.setErrorMessage("Could not move contribution to backup folder.");
}
}
return success;
}
/**
* Non-blocking call to remove a contribution in a new thread.
*/
void removeContribution(final Editor editor,
final ProgressMonitor pm,
final ErrorWidget statusBar) {
// final ContributionListing contribListing = ContributionListing.getInstance();
// final ProgressMonitor progressMonitor = ;
new Thread(new Runnable() {
public void run() {
remove(editor,
(pm != null) ? pm : new NullProgressMonitor(),
statusBar,
ContributionListing.getInstance());
}
}).start();
}
void remove(final Editor editor,
final ProgressMonitor pm,
final ErrorWidget statusBar,
final ContributionListing contribListing) {
pm.startTask("Removing", ProgressMonitor.UNKNOWN);
boolean doBackup = Preferences.getBoolean("contribution.backup.on_remove");
if (requiresRestart()) {
if (!doBackup || (doBackup && backup(editor, false, statusBar))) {
if (setDeletionFlag()) {
contribListing.replaceContribution(this, this);
}
}
} else {
boolean success = false;
if (doBackup) {
success = backup(editor, true, statusBar);
} else {
Base.removeDir(getFolder());
success = !getFolder().exists();
}
if (success) {
Contribution advertisedVersion =
contribListing.getAdvertisedContribution(this);
if (advertisedVersion == null) {
contribListing.removeContribution(this);
} else {
contribListing.replaceContribution(this, advertisedVersion);
}
} else {
// There was a failure backing up the folder
if (!doBackup) {
statusBar.setErrorMessage("Could not delete the contribution's files");
}
}
}
ContributionManager.refreshInstalled(editor);
pm.finished();
}
public File getFolder() {
return folder;
}
@@ -264,6 +355,33 @@ public abstract class InstalledContribution extends Contribution {
public boolean isInstalled() {
return folder != null;
}
boolean setDeletionFlag() {
// Only returns false if the file already exists, so we can
// ignore the return value.
try {
new File(getFolder(), DELETION_FLAG).createNewFile();
return true;
} catch (IOException e) {
return false;
}
}
boolean unsetDeletionFlag() {
return new File(getFolder(), DELETION_FLAG).delete();
}
boolean isDeletionFlagged() {
return isDeletionFlagged(getFolder());
}
static boolean isDeletionFlagged(File folder) {
return new File(folder, DELETION_FLAG).exists();
}
// public String getCategory() {
@@ -30,7 +30,7 @@ import processing.app.Base;
import processing.app.Mode;
public class ModeContribution extends InstalledContribution {
public class ModeContribution extends LocalContribution {
private Mode mode;
@@ -91,7 +91,7 @@ public class ModeContribution extends InstalledContribution {
for (ModeContribution contrib : contribModes) {
existing.put(contrib.getFolder(), contrib);
}
File[] potential = listCandidates(modesFolder, ContributionType.MODE);
File[] potential = ContributionType.MODE.listCandidates(modesFolder);
for (File folder : potential) {
if (!existing.containsKey(folder)) {
try {
@@ -88,9 +88,9 @@ public interface ProgressMonitor {
* task was cancelled.
*/
public void finished();
}
abstract class AbstractProgressMonitor implements ProgressMonitor {
boolean isCanceled = false;
@@ -31,7 +31,7 @@ import processing.app.Editor;
import processing.app.tools.Tool;
public class ToolContribution extends InstalledContribution implements Tool {
public class ToolContribution extends LocalContribution implements Tool {
private Tool tool;
@@ -69,7 +69,7 @@ public class ToolContribution extends InstalledContribution implements Tool {
static public ArrayList<ToolContribution> loadAll(File toolsFolder) {
File[] list = listCandidates(toolsFolder, ContributionType.TOOL);
File[] list = ContributionType.TOOL.listCandidates(toolsFolder);
ArrayList<ToolContribution> outgoing = new ArrayList<ToolContribution>();
for (File folder : list) {
try {
+34
View File
@@ -653,6 +653,11 @@ public class PShape implements PConstants {
}
fill = false;
fillColor = 0x0;
if (!setAmbient) {
ambientColor = fillColor;
}
}
@@ -665,6 +670,10 @@ public class PShape implements PConstants {
fill = true;
colorCalc(rgb);
fillColor = calcColor;
if (!setAmbient) {
ambientColor = fillColor;
}
}
@@ -677,6 +686,10 @@ public class PShape implements PConstants {
fill = true;
colorCalc(rgb, alpha);
fillColor = calcColor;
if (!setAmbient) {
ambientColor = fillColor;
}
}
@@ -689,6 +702,10 @@ public class PShape implements PConstants {
fill = true;
colorCalc(gray);
fillColor = calcColor;
if (!setAmbient) {
ambientColor = fillColor;
}
}
@@ -701,6 +718,15 @@ public class PShape implements PConstants {
fill = true;
colorCalc(gray, alpha);
fillColor = calcColor;
if (!setAmbient) {
ambient(fillColor);
setAmbient = false;
}
if (!setAmbient) {
ambientColor = fillColor;
}
}
@@ -713,6 +739,10 @@ public class PShape implements PConstants {
fill = true;
colorCalc(x, y, z);
fillColor = calcColor;
if (!setAmbient) {
ambientColor = fillColor;
}
}
@@ -725,6 +755,10 @@ public class PShape implements PConstants {
fill = true;
colorCalc(x, y, z, a);
fillColor = calcColor;
if (!setAmbient) {
ambientColor = fillColor;
}
}
+26 -12
View File
@@ -61,8 +61,6 @@ import processing.event.MouseEvent;
import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowUpdateEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.FBObject;
import com.jogamp.opengl.util.AnimatorBase;
@@ -630,6 +628,7 @@ public class PGL {
canvasAWT = new GLCanvas(caps);
canvasAWT.setBounds(0, 0, pg.width, pg.height);
canvasAWT.setBackground(new Color(pg.backgroundColor, true));
canvasAWT.setFocusable(true);
pg.parent.setLayout(new BorderLayout());
pg.parent.add(canvasAWT, BorderLayout.CENTER);
@@ -651,9 +650,7 @@ public class PGL {
canvasNEWT = new NewtCanvasAWT(window);
canvasNEWT.setBounds(0, 0, pg.width, pg.height);
canvasNEWT.setBackground(new Color(pg.backgroundColor, true));
pg.parent.setLayout(new BorderLayout());
pg.parent.add(canvasNEWT, BorderLayout.CENTER);
canvasNEWT.setFocusable(true);
NEWTMouseListener mouseListener = new NEWTMouseListener();
window.addMouseListener(mouseListener);
@@ -663,6 +660,9 @@ public class PGL {
window.addWindowListener(winListener);
canvasNEWT.addFocusListener(pg.parent); // So focus detection work.
pg.parent.setLayout(new BorderLayout());
pg.parent.add(canvasNEWT, BorderLayout.CENTER);
capabilities = window.getChosenGLCapabilities();
canvas = canvasNEWT;
canvasAWT = null;
@@ -3237,6 +3237,7 @@ public class PGL {
protected void nativeMouseEvent(com.jogamp.newt.event.MouseEvent nativeEvent,
int peAction) {
// if (!hasFocus) return;
int modifiers = nativeEvent.getModifiers();
int peModifiers = modifiers &
(InputEvent.SHIFT_MASK |
@@ -3296,31 +3297,44 @@ public class PGL {
pg.parent.postEvent(ke);
}
boolean hasFocus = true;
class NEWTWindowListener implements com.jogamp.newt.event.WindowListener {
@Override
public void windowGainedFocus(WindowEvent arg0) {
public void windowGainedFocus(com.jogamp.newt.event.WindowEvent arg0) {
PApplet.println("window gained focus");
pg.parent.focusGained(null);
hasFocus = true;
}
@Override
public void windowLostFocus(WindowEvent arg0) {
public void windowLostFocus(com.jogamp.newt.event.WindowEvent arg0) {
PApplet.println("window lost focus");
pg.parent.focusLost(null);
hasFocus = false;
}
@Override
public void windowDestroyNotify(WindowEvent arg0) { }
public void windowDestroyNotify(com.jogamp.newt.event.WindowEvent arg0) {
PApplet.println("destroy");
}
@Override
public void windowDestroyed(WindowEvent arg0) { }
public void windowDestroyed(com.jogamp.newt.event.WindowEvent arg0) {
PApplet.println("destroyed");
}
@Override
public void windowMoved(WindowEvent arg0) { }
public void windowMoved(com.jogamp.newt.event.WindowEvent arg0) {
PApplet.println("moved");
}
@Override
public void windowRepaint(WindowUpdateEvent arg0) { }
public void windowRepaint(com.jogamp.newt.event.WindowUpdateEvent arg0) {
PApplet.println("window repaint");
}
@Override
public void windowResized(WindowEvent arg0) { }
public void windowResized(com.jogamp.newt.event.WindowEvent arg0) { }
}
// NEWT mouse listener
+1 -1
View File
@@ -389,7 +389,7 @@ public class PGraphics2D extends PGraphicsOpenGL {
shape = new PShapeOpenGL(parent, PShape.PRIMITIVE);
shape.setKind(ELLIPSE);
} else if (kind == ARC) {
if (len != 6) {
if (len != 6 && len != 7) {
showWarning("Wrong number of parameters");
return null;
}
+1 -1
View File
@@ -260,7 +260,7 @@ public class PGraphics3D extends PGraphicsOpenGL {
shape = new PShapeOpenGL(parent, PShape.PRIMITIVE);
shape.setKind(ELLIPSE);
} else if (kind == ARC) {
if (len != 6) {
if (len != 6 && len != 7) {
showWarning("Wrong number of parameters");
return null;
}
@@ -4971,8 +4971,8 @@ public class PGraphicsOpenGL extends PGraphics {
// color buffer into it.
@Override
public void loadPixels() {
if (sized) {
// Something wrong going on with threading, sized can never be true if the
if (primarySurface && sized) {
// Something wrong going on with threading, sized can never be true if
// all the steps in a resize happen inside the Animation thread.
return;
}
@@ -5397,6 +5397,8 @@ public class PGraphicsOpenGL extends PGraphics {
textureMode = NORMAL;
boolean prevStroke = stroke;
stroke = false;
// int prevBlendMode = blendMode;
// blendMode(REPLACE);
PolyTexShader prevTexShader = polyTexShader;
polyTexShader = (PolyTexShader) shader;
beginShape(QUADS);
@@ -5414,6 +5416,7 @@ public class PGraphicsOpenGL extends PGraphics {
stroke = prevStroke;
lights = prevLights;
textureMode = prevTextureMode;
// blendMode(prevBlendMode);
if (!hints[DISABLE_DEPTH_TEST]) {
pgl.enable(PGL.DEPTH_TEST);
+36 -4
View File
@@ -3416,7 +3416,7 @@ public class PShapeOpenGL extends PShape {
d = params[3];
}
ellipseMode = CORNER;
// ellipseMode = CORNER;
inGeo.setMaterial(fillColor, strokeColor, strokeWeight,
ambientColor, specularColor, emissiveColor, shininess);
inGeo.setNormal(normalX, normalY, normalZ);
@@ -3428,20 +3428,24 @@ public class PShapeOpenGL extends PShape {
protected void tessellateArc() {
float a = 0, b = 0, c = 0, d = 0;
float start = 0, stop = 0;
if (params.length == 6) {
int mode = 0;
if (params.length == 6 || params.length == 7) {
a = params[0];
b = params[1];
c = params[2];
d = params[3];
start = params[4];
stop = params[5];
if (params.length == 7) {
mode = (int)(params[6]);
}
}
ellipseMode = CORNER;
// ellipseMode = CORNER;
inGeo.setMaterial(fillColor, strokeColor, strokeWeight,
ambientColor, specularColor, emissiveColor, shininess);
inGeo.setNormal(normalX, normalY, normalZ);
inGeo.addArc(a, b, c, d, start, stop, fill, stroke, ellipseMode);
inGeo.addArc(a, b, c, d, start, stop, fill, stroke, mode);
tessellator.tessellateTriangleFan();
}
@@ -4432,8 +4436,10 @@ public class PShapeOpenGL extends PShape {
protected void copyPolyVertices(int offset, int size) {
tessGeo.updatePolyVerticesBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyVertex);
tessGeo.polyVerticesBuffer.position(4 * offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT,
4 * size * PGL.SIZEOF_FLOAT, tessGeo.polyVerticesBuffer);
tessGeo.polyVerticesBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -4441,8 +4447,10 @@ public class PShapeOpenGL extends PShape {
protected void copyPolyColors(int offset, int size) {
tessGeo.updatePolyColorsBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyColor);
tessGeo.polyColorsBuffer.position(offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT,
size * PGL.SIZEOF_INT, tessGeo.polyColorsBuffer);
tessGeo.polyColorsBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -4450,8 +4458,10 @@ public class PShapeOpenGL extends PShape {
protected void copyPolyNormals(int offset, int size) {
tessGeo.updatePolyNormalsBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyNormal);
tessGeo.polyNormalsBuffer.position(3 * offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT,
3 * size * PGL.SIZEOF_FLOAT, tessGeo.polyNormalsBuffer);
tessGeo.polyNormalsBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -4459,8 +4469,10 @@ public class PShapeOpenGL extends PShape {
protected void copyPolyTexcoords(int offset, int size) {
tessGeo.updatePolyTexcoordsBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyTexcoord);
tessGeo.polyTexcoordsBuffer.position(2 * offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT,
2 * size * PGL.SIZEOF_FLOAT, tessGeo.polyTexcoordsBuffer);
tessGeo.polyTexcoordsBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -4468,8 +4480,10 @@ public class PShapeOpenGL extends PShape {
protected void copyPolyAmbient(int offset, int size) {
tessGeo.updatePolyAmbientBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyAmbient);
tessGeo.polyAmbientBuffer.position(offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT,
size * PGL.SIZEOF_INT, tessGeo.polyAmbientBuffer);
tessGeo.polyAmbientBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -4477,8 +4491,10 @@ public class PShapeOpenGL extends PShape {
protected void copyPolySpecular(int offset, int size) {
tessGeo.updatePolySpecularBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolySpecular);
tessGeo.polySpecularBuffer.position(offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT,
size * PGL.SIZEOF_INT, tessGeo.polySpecularBuffer);
tessGeo.polySpecularBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -4486,8 +4502,10 @@ public class PShapeOpenGL extends PShape {
protected void copyPolyEmissive(int offset, int size) {
tessGeo.updatePolyEmissiveBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyEmissive);
tessGeo.polyEmissiveBuffer.position(offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT,
size * PGL.SIZEOF_INT, tessGeo.polyEmissiveBuffer);
tessGeo.polyEmissiveBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -4495,8 +4513,10 @@ public class PShapeOpenGL extends PShape {
protected void copyPolyShininess(int offset, int size) {
tessGeo.updatePolyShininessBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyShininess);
tessGeo.polyShininessBuffer.position(offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_FLOAT,
size * PGL.SIZEOF_FLOAT, tessGeo.polyShininessBuffer);
tessGeo.polyShininessBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -4504,8 +4524,10 @@ public class PShapeOpenGL extends PShape {
protected void copyLineVertices(int offset, int size) {
tessGeo.updateLineVerticesBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineVertex);
tessGeo.lineVerticesBuffer.position(4 * offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT,
4 * size * PGL.SIZEOF_FLOAT, tessGeo.lineVerticesBuffer);
tessGeo.lineVerticesBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -4513,8 +4535,10 @@ public class PShapeOpenGL extends PShape {
protected void copyLineColors(int offset, int size) {
tessGeo.updateLineColorsBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineColor);
tessGeo.lineColorsBuffer.position(offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT,
size * PGL.SIZEOF_INT, tessGeo.lineColorsBuffer);
tessGeo.lineColorsBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -4522,8 +4546,10 @@ public class PShapeOpenGL extends PShape {
protected void copyLineAttributes(int offset, int size) {
tessGeo.updateLineAttribsBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineAttrib);
tessGeo.lineAttribsBuffer.position(4 * offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT,
4 * size * PGL.SIZEOF_FLOAT, tessGeo.lineAttribsBuffer);
tessGeo.lineAttribsBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -4531,8 +4557,10 @@ public class PShapeOpenGL extends PShape {
protected void copyPointVertices(int offset, int size) {
tessGeo.updatePointVerticesBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointVertex);
tessGeo.pointVerticesBuffer.position(4 * offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT,
4 * size * PGL.SIZEOF_FLOAT, tessGeo.pointVerticesBuffer);
tessGeo.pointVerticesBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -4540,8 +4568,10 @@ public class PShapeOpenGL extends PShape {
protected void copyPointColors(int offset, int size) {
tessGeo.updatePointColorsBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointColor);
tessGeo.pointColorsBuffer.position(offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT,
size * PGL.SIZEOF_INT,tessGeo.pointColorsBuffer);
tessGeo.pointColorsBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -4549,8 +4579,10 @@ public class PShapeOpenGL extends PShape {
protected void copyPointAttributes(int offset, int size) {
tessGeo.updatePointAttribsBuffer(offset, size);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointAttrib);
tessGeo.pointAttribsBuffer.position(2 * offset);
pgl.bufferSubData(PGL.ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT,
2 * size * PGL.SIZEOF_FLOAT, tessGeo.pointAttribsBuffer);
tessGeo.pointAttribsBuffer.rewind();
pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
+3 -1
View File
@@ -328,7 +328,6 @@ public class Texture implements PConstants {
public void set(int[] pixels, int x, int y, int w, int h, int format) {
if (pixels == null) {
pixels = null;
PGraphics.showWarning("The pixels array is null.");
return;
}
@@ -1283,6 +1282,9 @@ public class Texture implements PConstants {
// FBO copy:
pg.pushFramebuffer();
pg.setFramebuffer(tempFbo);
// Clear the color buffer to make sure that the alpha of the
pgl.clearColor(0, 0, 0, 0);
pgl.clear(PGL.COLOR_BUFFER_BIT);
if (scale) {
// Rendering tex into "this", and scaling the source rectangle
// to cover the entire destination region.
+7
View File
@@ -73,6 +73,13 @@ A https://github.com/processing/processing/issues/1598
X http://code.google.com/p/processing/issues/detail?id=1560
A disable stroke perspective by default (but this didn't fix it)
A fixed the disappearance, though still imperfect
A Fix get()/set() problems with images and OpenGL
A https://github.com/processing/processing/issues/1613
X http://code.google.com/p/processing/issues/detail?id=1575
o arc with large strokeWeight is very slow in P2D renderer
A marked WontFix, workaround is to create a PShape
A https://github.com/processing/processing/issues/1583
A http://code.google.com/p/processing/issues/detail?id=1545
cleaning/earlier
C textureWrap() CLAMP and REPEAT now added
+32 -31
View File
@@ -6,63 +6,63 @@
*/
int cuantos = 16000;
pelo[] lista ;
float[] z = new float[cuantos];
float[] phi = new float[cuantos];
float[] largos = new float[cuantos];
Pelo[] lista ;
float radio = 200;
float rx = 0;
float ry =0;
void setup() {
size(1024, 768, P3D);
noSmooth();
frameRate(120);
radio = height/3.5;
lista = new pelo[cuantos];
for (int i=0; i<cuantos; i++){
lista[i] = new pelo();
lista = new Pelo[cuantos];
for (int i = 0; i < lista.length; i++) {
lista[i] = new Pelo();
}
noiseDetail(3);
}
void draw() {
background(0);
translate(width/2,height/2);
float rxp = (mouseX-(width/2)) * 0.005;
float ryp = (mouseY-(height/2)) * 0.005;
rx = rx*0.9 + rxp*0.1;
ry = ry*0.9 + ryp*0.1;
float rxp = ((mouseX-(width/2))*0.005);
float ryp = ((mouseY-(height/2))*0.005);
rx = (rx*0.9)+(rxp*0.1);
ry = (ry*0.9)+(ryp*0.1);
translate(width/2, height/2);
rotateY(rx);
rotateX(ry);
fill(0);
noStroke();
sphere(radio);
for (int i=0;i<cuantos;i++){
for (int i = 0; i < lista.length; i++) {
lista[i].dibujar();
}
if (frameCount % 10 == 0) {
println(frameRate);
}
}
class pelo
class Pelo
{
float z = random(-radio,radio);
float z = random(-radio, radio);
float phi = random(TWO_PI);
float largo = random(1.15,1.2);
float largo = random(1.15, 1.2);
float theta = asin(z/radio);
void dibujar(){
Pelo() { // what's wrong with a constructor here
z = random(-radio, radio);
phi = random(TWO_PI);
largo = random(1.15, 1.2);
theta = asin(z/radio);
}
float off = (noise(millis() * 0.0005,sin(phi))-0.5) * 0.3;
float offb = (noise(millis() * 0.0007,sin(z) * 0.01)-0.5) * 0.3;
void dibujar() {
float off = (noise(millis() * 0.0005, sin(phi))-0.5) * 0.3;
float offb = (noise(millis() * 0.0007, sin(z) * 0.01)-0.5) * 0.3;
float thetaff = theta+off;
float phff = phi+offb;
@@ -77,13 +77,14 @@ class pelo
float xb = xo * largo;
float yb = yo * largo;
float zb = zo * largo;
strokeWeight(1);
beginShape(LINES);
stroke(0);
vertex(x,y,z);
stroke(200,150);
vertex(xb,yb,zb);
vertex(x, y, z);
stroke(200, 150);
vertex(xb, yb, zb);
endShape();
}
}
@@ -45,17 +45,15 @@ void setup() {
// Make a primitive (Rectangle) PShape
PShape rectangle = createShape(RECT,-10,-10,20,20);
rectangle.setFill(false);
rectangle.setStroke(255);
rectangle.setStroke(color(255));
// Add them all to the group
group.addChild(star);
group.addChild(path);
group.addChild(rectangle); // Rectangle is missing???
group.addChild(rectangle);
}
void draw() {
// We can access them individually via the group PShape
PShape rectangle = group.getChild(2);
// Shapes can be rotated