Skip to content

Improve Examples menu #5178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 12, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 130 additions & 37 deletions app/src/processing/app/Base.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,6 @@
*/
public class Base {

public static final Predicate<UserLibrary> CONTRIBUTED = library -> library.getTypes() == null || library.getTypes().isEmpty() || library.getTypes().contains("Contributed");
public static final Predicate<UserLibrary> RETIRED = library -> library.getTypes() != null && library.getTypes().contains("Retired");
public static final Predicate<UserLibrary> COMPATIBLE = library -> library.getArchitectures() != null && (library.getArchitectures().contains("*") || library.getArchitectures().contains(BaseNoGui.getTargetPlatform().getId()));

private static final int RECENT_SKETCHES_MAX_SIZE = 10;

private static boolean commandLine;
Expand Down Expand Up @@ -1100,30 +1096,6 @@ protected void rebuildSketchbookMenu(JMenu menu) {
}
}

public LibraryList getIDELibs() {
LibraryList installedLibraries = new LibraryList(BaseNoGui.librariesIndexer.getInstalledLibraries());
List<UserLibrary> libs = installedLibraries.stream()
.filter(CONTRIBUTED.negate())
.filter(RETIRED.negate())
.filter(COMPATIBLE)
.collect(Collectors.toList());
return new LibraryList(libs);
}

public LibraryList getIDERetiredLibs() {
LibraryList installedLibraries = new LibraryList(BaseNoGui.librariesIndexer.getInstalledLibraries());
List<UserLibrary> libs = installedLibraries.stream()
.filter(RETIRED)
.collect(Collectors.toList());
return new LibraryList(libs);
}

public LibraryList getUserLibs() {
LibraryList installedLibraries = new LibraryList(BaseNoGui.librariesIndexer.getInstalledLibraries());
List<UserLibrary> libs = installedLibraries.stream().filter(CONTRIBUTED).collect(Collectors.toList());
return new LibraryList(libs);
}

private List<ContributedLibrary> getSortedLibraries() {
List<ContributedLibrary> installedLibraries = new LinkedList<ContributedLibrary>(BaseNoGui.librariesIndexer.getInstalledLibraries());
Collections.sort(installedLibraries, new LibraryByTypeComparator());
Expand Down Expand Up @@ -1206,36 +1178,157 @@ public void rebuildExamplesMenu(JMenu menu) {
menu.addSeparator();
}

// Libraries can come from 4 locations: collect info about all four
File ideLibraryPath = BaseNoGui.getContentFile("libraries");
File sketchbookLibraryPath = BaseNoGui.getSketchbookLibrariesFolder();
File platformLibraryPath = null;
File referencedPlatformLibraryPath = null;
String platformName = null;
String referencedPlatformName = null;
String myArch = null;
TargetPlatform targetPlatform = BaseNoGui.getTargetPlatform();
if (targetPlatform != null) {
myArch = targetPlatform.getId();
platformName = targetPlatform.getPreferences().get("name");
platformLibraryPath = new File(targetPlatform.getFolder(), "libraries");
String core = BaseNoGui.getBoardPreferences().get("build.core", "arduino");
if (core.contains(":")) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't there existing code to handle finding out the referenced platform? Or is that removed and moved into arduino-builder now? This would seem like the wrong place to have this logic, perhaps moving it into a Platform method might be more appropriate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If TargetPlatform has a function to get the referenced platform within its API, I agree it should be used rather than parsing the build.core pref. Likewise for finding the human-readable name of the platform. But I didn't see anything like this inside TargetPlatform. I'd be happy to change this to use an official API... I just need someone to tell me which API does this?

String refcore = core.split(":")[0];
TargetPlatform referencedPlatform = BaseNoGui.getTargetPlatform(refcore, myArch);
if (referencedPlatform != null) {
referencedPlatformName = referencedPlatform.getPreferences().get("name");
referencedPlatformLibraryPath = new File(referencedPlatform.getFolder(), "libraries");
}
}
}

// Divide the libraries into 7 lists, corresponding to the 4 locations
// with the retired IDE libs further divided into their own list, and
// any incompatible sketchbook libs further divided into their own list.
// The 7th list of "other" libraries should always be empty, but serves
// as a safety feature to prevent any library from vanishing.
LibraryList allLibraries = new LibraryList(BaseNoGui.librariesIndexer.getInstalledLibraries());
LibraryList ideLibs = new LibraryList();
LibraryList retiredIdeLibs = new LibraryList();
LibraryList platformLibs = new LibraryList();
LibraryList referencedPlatformLibs = new LibraryList();
LibraryList sketchbookLibs = new LibraryList();
LibraryList sketchbookIncompatibleLibs = new LibraryList();
LibraryList otherLibs = new LibraryList();
for (UserLibrary lib : allLibraries) {
// Get the library's location - used for sorting into categories
File libraryLocation = lib.getInstalledFolder().getParentFile();
// Is this library compatible?
List<String> arch = lib.getArchitectures();
boolean compatible;
if (myArch == null || arch == null || arch.contains("*")) {
compatible = true;
} else {
compatible = arch.contains(myArch);
}
// IDE Libaries (including retired)
if (libraryLocation.equals(ideLibraryPath)) {
if (compatible) {
// only compatible IDE libs are shown
boolean retired = false;
List<String> types = lib.getTypes();
if (types != null) retired = types.contains("Retired");
if (retired) {
retiredIdeLibs.add(lib);
} else {
ideLibs.add(lib);
}
}
// Platform Libraries
} else if (libraryLocation.equals(platformLibraryPath)) {
// all platform libs are assumed to be compatible
platformLibs.add(lib);
// Referenced Platform Libraries
} else if (libraryLocation.equals(referencedPlatformLibraryPath)) {
// all referenced platform libs are assumed to be compatible
referencedPlatformLibs.add(lib);
// Sketchbook Libraries (including incompatible)
} else if (libraryLocation.equals(sketchbookLibraryPath)) {
if (compatible) {
sketchbookLibs.add(lib);
} else {
sketchbookIncompatibleLibs.add(lib);
}
// Other libraries of unknown type (should never occur)
} else {
otherLibs.add(lib);
}
}

// Add examples from libraries
LibraryList ideLibs = getIDELibs();
ideLibs.sort();
if (!ideLibs.isEmpty()) {
label = new JMenuItem(tr("Examples from Libraries"));
ideLibs.sort();
label = new JMenuItem(tr("Examples from Built-in Libraries"));
label.setEnabled(false);
menu.add(label);
}
for (UserLibrary lib : ideLibs) {
addSketchesSubmenu(menu, lib);
}

LibraryList retiredIdeLibs = getIDERetiredLibs();
retiredIdeLibs.sort();
if (!retiredIdeLibs.isEmpty()) {
retiredIdeLibs.sort();
JMenu retired = new JMenu(tr("RETIRED"));
menu.add(retired);
for (UserLibrary lib : retiredIdeLibs) {
addSketchesSubmenu(retired, lib);
}
}

LibraryList userLibs = getUserLibs();
if (userLibs.size() > 0) {
if (!platformLibs.isEmpty()) {
menu.addSeparator();
userLibs.sort();
platformLibs.sort();
label = new JMenuItem(I18n.format(tr("Examples from {0} Libraries"), platformName));
label.setEnabled(false);
menu.add(label);
for (UserLibrary lib : platformLibs) {
addSketchesSubmenu(menu, lib);
}
}

if (!referencedPlatformLibs.isEmpty()) {
menu.addSeparator();
referencedPlatformLibs.sort();
label = new JMenuItem(I18n.format(tr("Examples from {0} Libraries"), referencedPlatformName));
label.setEnabled(false);
menu.add(label);
for (UserLibrary lib : referencedPlatformLibs) {
addSketchesSubmenu(menu, lib);
}
}

if (!sketchbookLibs.isEmpty()) {
menu.addSeparator();
sketchbookLibs.sort();
label = new JMenuItem(tr("Examples from Custom Libraries"));
label.setEnabled(false);
menu.add(label);
for (UserLibrary lib : userLibs) {
for (UserLibrary lib : sketchbookLibs) {
addSketchesSubmenu(menu, lib);
}
}

if (!sketchbookIncompatibleLibs.isEmpty()) {
sketchbookIncompatibleLibs.sort();
JMenu incompatible = new JMenu(tr("INCOMPATIBLE"));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this list the boardname explicitly, e.g. "Incompatible with " to be more clear?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. I tried to copy the style used above for retired libraries.

If the string becomes "Incompatible with {0}", what string should be shown? If the platform human readable name is used, which one do you show if there's referenced platform? Always the main platform? What if it's null? If the architecture ID is used, will it be human readable? Will end users understand "samd"?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking it should just list the board selected, not the architecture, since the board name will have more meaning than the architecture name. However, it does hide some information, since the real incompatibility is with the architecture used by the board of course.

menu.add(incompatible);
for (UserLibrary lib : sketchbookIncompatibleLibs) {
addSketchesSubmenu(incompatible, lib);
}
}

if (!otherLibs.isEmpty()) {
menu.addSeparator();
otherLibs.sort();
label = new JMenuItem(tr("Examples from Other Libraries"));
label.setEnabled(false);
menu.add(label);
for (UserLibrary lib : otherLibs) {
addSketchesSubmenu(menu, lib);
}
}
Expand Down