mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
cleaning up and debugging contrib mgr; start work on inline progress icon
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2013-22 The Processing Foundation
|
||||
Copyright (c) 2013-23 The Processing Foundation
|
||||
Copyright (c) 2011-12 Ben Fry and Casey Reas
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@@ -109,8 +109,8 @@ public class ContribProgress {
|
||||
public void cancelAction() { }
|
||||
|
||||
|
||||
public boolean isCanceled() {
|
||||
return canceled;
|
||||
public boolean notCanceled() {
|
||||
return !canceled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -140,20 +140,20 @@ public class ContributionListing {
|
||||
}
|
||||
|
||||
|
||||
protected void replaceContribution(Contribution oldLib, Contribution newLib) {
|
||||
if (oldLib != null && newLib != null) {
|
||||
if (oldLib.getImports() != null) {
|
||||
for (String importName : oldLib.getImports()) {
|
||||
protected void replaceContribution(Contribution oldContrib, Contribution newContrib) {
|
||||
if (oldContrib != null && newContrib != null) {
|
||||
if (oldContrib.getImports() != null) {
|
||||
for (String importName : oldContrib.getImports()) {
|
||||
if (getLibrariesByImportHeader().containsKey(importName)) {
|
||||
getLibrariesByImportHeader().put(importName, newLib);
|
||||
getLibrariesByImportHeader().put(importName, newContrib);
|
||||
}
|
||||
}
|
||||
}
|
||||
allContributions.remove(oldLib);
|
||||
allContributions.add(newLib);
|
||||
allContributions.remove(oldContrib);
|
||||
allContributions.add(newContrib);
|
||||
|
||||
for (ListPanel listener : listPanels) {
|
||||
listener.contributionChanged(oldLib, newLib);
|
||||
listener.contributionChanged(oldContrib, newContrib);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,7 +227,7 @@ public class ContributionListing {
|
||||
}
|
||||
ContributionManager.download(url, makeContribsBlob(base),
|
||||
tempContribFile, progress);
|
||||
if (!progress.isCanceled() && !progress.isException()) {
|
||||
if (progress.notCanceled() && !progress.isException()) {
|
||||
if (listingFile.exists()) {
|
||||
listingFile.delete(); // may silently fail, but below may still work
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ public class ContributionManager {
|
||||
int amount;
|
||||
if (progress != null) {
|
||||
int total = 0;
|
||||
while (!progress.isCanceled() && (amount = in.read(b)) != -1) {
|
||||
while (progress.notCanceled() && (amount = in.read(b)) != -1) {
|
||||
out.write(b, 0, amount);
|
||||
total += amount;
|
||||
progress.setProgress(total);
|
||||
@@ -154,7 +154,7 @@ public class ContributionManager {
|
||||
try {
|
||||
download(url, null, contribZip, downloadProgress);
|
||||
|
||||
if (!downloadProgress.isCanceled() && !downloadProgress.isException()) {
|
||||
if (downloadProgress.notCanceled() && !downloadProgress.isException()) {
|
||||
installProgress.startTask(Language.text("contrib.progress.installing"));
|
||||
final LocalContribution contribution =
|
||||
ad.install(base, contribZip, false, status);
|
||||
|
||||
@@ -324,6 +324,11 @@ public class ContributionTab extends JPanel {
|
||||
}
|
||||
|
||||
|
||||
protected boolean filterHasFocus() {
|
||||
return filterField != null && filterField.hasFocus();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// TODO Why is this entire set of code only running when Editor
|
||||
// is not null... And what's it doing anyway? Shouldn't it run
|
||||
@@ -369,13 +374,13 @@ public class ContributionTab extends JPanel {
|
||||
*/
|
||||
|
||||
|
||||
public void updateStatusDetail(StatusDetail detail) {
|
||||
statusPanel.updateDetail(detail);
|
||||
protected StatusDetail createStatusDetail() {
|
||||
return new StatusDetail(base, statusPanel);
|
||||
}
|
||||
|
||||
|
||||
public boolean filterHasFocus() {
|
||||
return filterField != null && filterField.hasFocus();
|
||||
protected void updateStatusDetail(StatusDetail detail) {
|
||||
statusPanel.updateDetail(detail);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
package processing.app.contrib;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -56,6 +57,7 @@ public class ListPanel extends JPanel implements Scrollable {
|
||||
protected ContributionTableModel model;
|
||||
|
||||
// state icons appearing to the left side of the list
|
||||
static final int ICON_SIZE = 16;
|
||||
Icon upToDateIcon;
|
||||
Icon updateAvailableIcon;
|
||||
Icon incompatibleIcon;
|
||||
@@ -197,17 +199,30 @@ public class ListPanel extends JPanel implements Scrollable {
|
||||
rowColor = Theme.getColor("manager.list.background.color");
|
||||
table.setBackground(rowColor);
|
||||
|
||||
foundationIcon = Toolkit.renderIcon("manager/foundation", Theme.get("manager.list.foundation.color"), 16);
|
||||
foundationIcon = Toolkit.renderIcon("manager/foundation", Theme.get("manager.list.foundation.color"), ICON_SIZE);
|
||||
|
||||
upToDateIcon = Toolkit.renderIcon("manager/list-up-to-date", Theme.get("manager.list.icon.color"), 16);
|
||||
updateAvailableIcon = Toolkit.renderIcon("manager/list-update-available", Theme.get("manager.list.icon.color"), 16);
|
||||
incompatibleIcon = Toolkit.renderIcon("manager/list-incompatible", Theme.get("manager.list.icon.color"), 16);
|
||||
downloadingIcon = Toolkit.renderIcon("manager/list-downloading", Theme.get("manager.list.icon.color"), 16);
|
||||
upToDateIcon = Toolkit.renderIcon("manager/list-up-to-date", Theme.get("manager.list.icon.color"), ICON_SIZE);
|
||||
updateAvailableIcon = Toolkit.renderIcon("manager/list-update-available", Theme.get("manager.list.icon.color"), ICON_SIZE);
|
||||
incompatibleIcon = Toolkit.renderIcon("manager/list-incompatible", Theme.get("manager.list.icon.color"), ICON_SIZE);
|
||||
downloadingIcon = Toolkit.renderIcon("manager/list-downloading", Theme.get("manager.list.icon.color"), ICON_SIZE);
|
||||
|
||||
((PdeScrollBarUI) scrollPane.getVerticalScrollBar().getUI()).updateTheme();
|
||||
}
|
||||
|
||||
|
||||
Icon renderProgressIcon(float amount) {
|
||||
final int scale = Toolkit.highResImages() ? 2 : 1;
|
||||
final int dim = ICON_SIZE * scale;
|
||||
Image image = new BufferedImage(dim, dim, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2 = (Graphics2D) image.getGraphics();
|
||||
g2.scale(scale, scale);
|
||||
g2.setColor(Color.ORANGE);
|
||||
g2.fillRect(0, 0, (int) (amount * ICON_SIZE), ICON_SIZE);
|
||||
g2.dispose();
|
||||
return Toolkit.wrapIcon(image);
|
||||
}
|
||||
|
||||
|
||||
// TODO remove this, yuck [fry 220313]
|
||||
protected int getScrollBarWidth() {
|
||||
return scrollPane.getVerticalScrollBar().getPreferredSize().width;
|
||||
@@ -304,9 +319,9 @@ public class ListPanel extends JPanel implements Scrollable {
|
||||
if (sortKey != null && table.convertColumnIndexToView(sortKey.getColumn()) == column) {
|
||||
switch (sortKey.getSortOrder()) {
|
||||
case ASCENDING:
|
||||
return " \u2193";
|
||||
return " ↓";
|
||||
case DESCENDING:
|
||||
return " \u2191";
|
||||
return " ↑";
|
||||
}
|
||||
}
|
||||
// if not sorting on this column
|
||||
@@ -389,6 +404,8 @@ public class ListPanel extends JPanel implements Scrollable {
|
||||
if (detail != null && (detail.updateInProgress || detail.installInProgress)) {
|
||||
// Display "loading" icon if download/install in progress
|
||||
icon = downloadingIcon;
|
||||
// float amount = detail.getProgressAmount();
|
||||
// icon = (amount == -1) ? downloadingIcon : renderProgressIcon(amount);
|
||||
} else if (contribution.isInstalled()) {
|
||||
if (!contribution.isCompatible(Base.getRevision())) {
|
||||
icon = incompatibleIcon;
|
||||
@@ -642,8 +659,7 @@ public class ListPanel extends JPanel implements Scrollable {
|
||||
// new Exception().printStackTrace(System.out);
|
||||
// long t1 = System.currentTimeMillis();
|
||||
//StatusPanelDetail newPanel = new StatusPanelDetail(this);
|
||||
StatusDetail newPanel =
|
||||
new StatusDetail(contributionTab.base, contributionTab.statusPanel);
|
||||
StatusDetail newPanel = contributionTab.createStatusDetail();
|
||||
detailForContrib.put(contribution, newPanel);
|
||||
newPanel.setContrib(contribution);
|
||||
// add(newPanel);
|
||||
|
||||
@@ -30,6 +30,7 @@ import javax.swing.JProgressBar;
|
||||
|
||||
import processing.app.*;
|
||||
import processing.app.laf.PdeProgressBarUI;
|
||||
import processing.app.ui.Toolkit;
|
||||
|
||||
|
||||
/**
|
||||
@@ -78,11 +79,11 @@ class StatusDetail {
|
||||
}
|
||||
|
||||
|
||||
private void installContribution(AvailableContribution info) {
|
||||
if (info.link == null) {
|
||||
statusPanel.setErrorMessage(Language.interpolate("contrib.unsupported_operating_system", info.getType()));
|
||||
protected float getProgressAmount() {
|
||||
if (progressBar.isIndeterminate()) {
|
||||
return -1;
|
||||
} else {
|
||||
installContribution(info, info.link);
|
||||
return (float) progressBar.getValue() / progressBar.getMaximum();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,12 +142,20 @@ class StatusDetail {
|
||||
|
||||
|
||||
protected void install() {
|
||||
//clearStatusMessage();
|
||||
statusPanel.clearMessage();
|
||||
installInProgress = true;
|
||||
if (contrib instanceof AvailableContribution) {
|
||||
installContribution((AvailableContribution) contrib);
|
||||
ContributionListing.getInstance().replaceContribution(contrib, contrib);
|
||||
if (contrib instanceof AvailableContribution info) {
|
||||
if (info.link == null) {
|
||||
statusPanel.setErrorMessage(Language.interpolate("contrib.missing_link", info.getType()));
|
||||
} else {
|
||||
installContribution(info, info.link);
|
||||
// NOTE As of 4.1.1 this was being called even if the error message
|
||||
// above was getting called. Probably harmless, especially since
|
||||
// the error may never happen, but still… weird. [fry 230114]
|
||||
// TODO More importantly, why is this being called? Seems like this
|
||||
// should be doing an actual replacement. [fry 230114]
|
||||
ContributionListing.getInstance().replaceContribution(contrib, contrib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +164,6 @@ class StatusDetail {
|
||||
// of all things, calls install() in its finishedAction() method.
|
||||
// FFS this is gross. [fry 220311]
|
||||
protected void update() {
|
||||
//clearStatusMessage();
|
||||
statusPanel.clearMessage();
|
||||
updateInProgress = true;
|
||||
|
||||
@@ -163,19 +171,8 @@ class StatusDetail {
|
||||
|
||||
// TODO not really a 'restart' anymore, just requires care [fry 220312]
|
||||
if (contrib.getType().requiresRestart()) {
|
||||
// For the special "Updates" tab in the manager, there are no progress
|
||||
// bars, so if that's what we're doing, this will create a dummy bar.
|
||||
// TODO Not a good workaround [fry 220312]
|
||||
// TODO This is really, really gross [fry 221104]
|
||||
if (progressBar == null) {
|
||||
// This was removed in 4.x and brought back for 4.0.2 because
|
||||
// it broke the "Update All" option in the Contributions Manager.
|
||||
// https://github.com/processing/processing4/issues/567
|
||||
progressBar = new JProgressBar();
|
||||
} else {
|
||||
progressBar.setVisible(true);
|
||||
progressBar.setIndeterminate(true);
|
||||
}
|
||||
progressBar.setVisible(true);
|
||||
progressBar.setIndeterminate(true);
|
||||
|
||||
ContribProgress progress = new ContribProgress(progressBar) {
|
||||
@Override
|
||||
|
||||
@@ -118,27 +118,7 @@ class StatusPanel extends JPanel {
|
||||
updateDetail(currentDetail);
|
||||
});
|
||||
|
||||
progressBar = new JProgressBar();
|
||||
/*
|
||||
progressBar = new JProgressBar() {
|
||||
@Override
|
||||
public void setBackground(Color c) {
|
||||
new Exception("setting bg to " + c).printStackTrace(System.out);
|
||||
super.setBackground(c);
|
||||
}
|
||||
};
|
||||
*/
|
||||
progressBar.setStringPainted(true);
|
||||
progressBar.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
//progressBar.setOpaque(true);
|
||||
|
||||
resetProgressBar();
|
||||
|
||||
final int high = progressBar.getPreferredSize().height;
|
||||
Dimension dim = new Dimension(BUTTON_WIDTH, high);
|
||||
progressBar.setPreferredSize(dim);
|
||||
progressBar.setMaximumSize(dim);
|
||||
progressBar.setMinimumSize(dim);
|
||||
buildProgressBar();
|
||||
|
||||
updateLabel = new JLabel(" ");
|
||||
// updateLabel.setFont(buttonFont);
|
||||
@@ -209,8 +189,6 @@ class StatusPanel extends JPanel {
|
||||
layout.linkSize(SwingConstants.HORIZONTAL,
|
||||
installButton, progressBar, updateButton, removeButton);
|
||||
|
||||
progressBar.setVisible(false);
|
||||
|
||||
installButton.setEnabled(false);
|
||||
updateButton.setEnabled(false);
|
||||
removeButton.setEnabled(false);
|
||||
@@ -223,6 +201,22 @@ class StatusPanel extends JPanel {
|
||||
}
|
||||
|
||||
|
||||
protected void buildProgressBar() {
|
||||
progressBar = new JProgressBar();
|
||||
progressBar.setStringPainted(true);
|
||||
progressBar.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
//progressBar.setOpaque(true);
|
||||
|
||||
resetProgressBar();
|
||||
|
||||
final int high = progressBar.getPreferredSize().height;
|
||||
Dimension dim = new Dimension(BUTTON_WIDTH, high);
|
||||
progressBar.setPreferredSize(dim);
|
||||
progressBar.setMaximumSize(dim);
|
||||
progressBar.setMinimumSize(dim);
|
||||
}
|
||||
|
||||
|
||||
protected void resetProgressBar() {
|
||||
// TODO is this overkill for a reset? is this really only being used
|
||||
// when we mean to call setVisible(false)? [fry 220311]
|
||||
|
||||
@@ -28,8 +28,8 @@ public class UpdateContributionTab extends ContributionTab {
|
||||
public UpdateContributionTab(ManagerFrame dialog) {
|
||||
super(dialog);
|
||||
|
||||
// Filter to show only the contributions that have updates
|
||||
// or are fake section header "contributions".
|
||||
// Filter to show only the contributions with updates available,
|
||||
// or are section headers (which are fake contributions).
|
||||
filter = contrib -> {
|
||||
if (contrib instanceof ListPanel.SectionHeaderContribution) {
|
||||
return true;
|
||||
@@ -86,10 +86,4 @@ public class UpdateContributionTab extends ContributionTab {
|
||||
|
||||
//setBackground(Color.WHITE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateStatusDetail(StatusDetail detail) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,4 +66,10 @@ public class UpdateStatusPanel extends StatusPanel {
|
||||
protected void setUpdateEnabled(boolean updateEnabled) {
|
||||
updateButton.setEnabled(updateEnabled);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void updateDetail(StatusDetail detail) {
|
||||
detail.setProgressBar(progressBar);
|
||||
}
|
||||
}
|
||||
@@ -562,7 +562,7 @@ contrib.progress.installing = Installing
|
||||
contrib.progress.starting = Starting
|
||||
contrib.progress.downloading = Downloading
|
||||
contrib.download_error = An error occured while downloading the contribution.
|
||||
contrib.unsupported_operating_system = Your operating system does not appear to be supported. You should visit the %s\’s library for more info.
|
||||
contrib.missing_link = The download link for this %s is missing, please contact the author.
|
||||
contrib.category.3d = 3D
|
||||
contrib.category.animation = Animation
|
||||
contrib.category.data = Data
|
||||
|
||||
@@ -67,7 +67,15 @@ X should be using Base.getInstalledContribs() instead of rewriting its own
|
||||
X ManagerFrame.downloadAndUpdateContributionListing()
|
||||
X should not even be run, because the contribs load on startup
|
||||
X but ContributionTab.tryAgainButton needs to be able to request re-download
|
||||
X removed old workaround for NPE
|
||||
X https://github.com/processing/processing/issues/3667
|
||||
|
||||
_ contrib categories are broken
|
||||
_ showing 'all' on all tabs, not showing categories at all for libs
|
||||
|
||||
_ updateDetail() call in StatusPanel.updateTheme()
|
||||
_ move to ListPanel.updateTheme() (why wasn't it there?)
|
||||
_ ugh, it's called twice, right nearby each other; yikes
|
||||
|
||||
_ rip out JProgressBar from StatusPanel/StatusDetail
|
||||
_ show progress in the list instead
|
||||
|
||||
Reference in New Issue
Block a user