cleaning up and debugging contrib mgr; start work on inline progress icon

This commit is contained in:
Ben Fry
2023-01-14 10:09:25 -05:00
parent b1a0f2a129
commit b8988b8af0
11 changed files with 101 additions and 81 deletions
@@ -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);
}
+25 -9
View File
@@ -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
+17 -23
View File
@@ -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);
}
}
+1 -1
View File
@@ -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
+8
View File
@@ -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