From 68a50fdba28ffbd983d3b69607ae7d7f684bc286 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 3 Feb 2022 14:36:43 -0500 Subject: [PATCH] rewrite sketchbook window handling, add refresh/open buttons --- app/src/processing/app/Base.java | 58 +++++++++++- app/src/processing/app/Mode.java | 44 --------- app/src/processing/app/Sketch.java | 4 +- app/src/processing/app/ui/Editor.java | 2 +- .../processing/app/ui/SketchbookFrame.java | 91 ++++++++++++++----- todo.txt | 10 +- 6 files changed, 135 insertions(+), 74 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index b680cdc9c..44b1f7357 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -509,7 +509,7 @@ public class Base { defaultFileMenu.add(item); item = Toolkit.newJMenuItemShift(Language.text("menu.file.sketchbook"), 'K'); - item.addActionListener(e -> getNextMode().showSketchbookFrame()); + item.addActionListener(e -> showSketchbookFrame()); defaultFileMenu.add(item); item = Toolkit.newJMenuItemShift(Language.text("menu.file.examples"), 'O'); @@ -1727,18 +1727,68 @@ public class Base { } + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + protected SketchbookFrame sketchbookFrame; + + public DefaultMutableTreeNode buildSketchbookTree() { + DefaultMutableTreeNode sbNode = + new DefaultMutableTreeNode(Language.text("sketchbook.tree")); + try { + addSketches(sbNode, Base.getSketchbookFolder(), false); + } catch (IOException e) { + e.printStackTrace(); + } + return sbNode; + } + + + /** Sketchbook has changed, update it on next viewing. */ + public void rebuildSketchbookFrame() { + if (sketchbookFrame != null) { + sketchbookFrame.rebuild(); + /* + boolean visible = sketchbookFrame.isVisible(); + Rectangle bounds = null; + if (visible) { + bounds = sketchbookFrame.getBounds(); + sketchbookFrame.setVisible(false); + sketchbookFrame.dispose(); + } + sketchbookFrame = null; + if (visible) { + showSketchbookFrame(); + sketchbookFrame.setBounds(bounds); + } + */ + } + } + + + public void showSketchbookFrame() { + if (sketchbookFrame == null) { + sketchbookFrame = new SketchbookFrame(this); + } + sketchbookFrame.setVisible(); + } + + /** * Synchronous version of rebuild, used when the sketchbook folder has * changed, so that the libraries are properly re-scanned before those menus * (and the examples window) are rebuilt. */ - protected void rebuildSketchbookMenus() { + public void rebuildSketchbook() { for (Mode mode : getModeList()) { mode.rebuildImportMenu(); // calls rebuildLibraryList mode.rebuildToolbarMenu(); mode.rebuildExamplesFrame(); - mode.rebuildSketchbookFrame(); } + // Unlike libraries, examples, etc, the sketchbook is global + // (because you need to be able to open sketches from the Mode + // that you're not currently using). + rebuildSketchbookFrame(); } @@ -2068,7 +2118,7 @@ public class Base { public void setSketchbookFolder(File folder) { sketchbookFolder = folder; Preferences.setSketchbookPath(folder.getAbsolutePath()); - rebuildSketchbookMenus(); + rebuildSketchbook(); makeSketchbookSubfolders(); } diff --git a/app/src/processing/app/Mode.java b/app/src/processing/app/Mode.java index 384da8388..389f8cc23 100644 --- a/app/src/processing/app/Mode.java +++ b/app/src/processing/app/Mode.java @@ -39,7 +39,6 @@ import processing.app.ui.EditorException; import processing.app.ui.EditorState; import processing.app.ui.ExamplesFrame; import processing.app.ui.Recent; -import processing.app.ui.SketchbookFrame; import processing.app.ui.Toolkit; import processing.core.PApplet; @@ -63,7 +62,6 @@ public abstract class Mode { protected JMenu importMenu; protected ExamplesFrame examplesFrame; - protected SketchbookFrame sketchbookFrame; // popup menu used for the toolbar protected JMenu toolbarMenu; @@ -655,48 +653,6 @@ public abstract class Mode { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - public DefaultMutableTreeNode buildSketchbookTree() { - DefaultMutableTreeNode sbNode = - new DefaultMutableTreeNode(Language.text("sketchbook.tree")); - try { - base.addSketches(sbNode, Base.getSketchbookFolder(), false); - } catch (IOException e) { - e.printStackTrace(); - } - return sbNode; - } - - - /** Sketchbook has changed, update it on next viewing. */ - public void rebuildSketchbookFrame() { - if (sketchbookFrame != null) { - boolean visible = sketchbookFrame.isVisible(); - Rectangle bounds = null; - if (visible) { - bounds = sketchbookFrame.getBounds(); - sketchbookFrame.setVisible(false); - sketchbookFrame.dispose(); - } - sketchbookFrame = null; - if (visible) { - showSketchbookFrame(); - sketchbookFrame.setBounds(bounds); - } - } - } - - - public void showSketchbookFrame() { - if (sketchbookFrame == null) { - sketchbookFrame = new SketchbookFrame(base, this); - } - sketchbookFrame.setVisible(); - } - - - // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - /** * Get an ImageIcon object from the Mode folder. * Or when prefixed with /lib, load it from the main /lib folder. diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index eac622bea..8dba8affe 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -677,7 +677,7 @@ public class Sketch { // make a new sketch and rebuild the sketch menu //editor.handleNewUnchecked(); //editor.handleClose2(); - editor.getBase().rebuildSketchbookMenus(); + editor.getBase().rebuildSketchbook(); editor.getBase().handleClose(editor, false); } else { @@ -1218,7 +1218,7 @@ public class Sketch { calcModified(); // System.out.println("modified is now " + modified); editor.updateTitle(); - editor.getBase().rebuildSketchbookMenus(); + editor.getBase().rebuildSketchbook(); if (renaming) { // only update the Recent menu if it's a rename, not a Save As // https://github.com/processing/processing/issues/5902 diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index a414374ac..55d899bf9 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -669,7 +669,7 @@ public abstract class Editor extends JFrame implements RunnerListener { // fileMenu.add(base.getSketchbookMenu()); item = Toolkit.newJMenuItemShift(Language.text("menu.file.sketchbook"), 'K'); - item.addActionListener(e -> mode.showSketchbookFrame()); + item.addActionListener(e -> base.showSketchbookFrame()); fileMenu.add(item); item = Toolkit.newJMenuItemShift(Language.text("menu.file.examples"), 'O'); diff --git a/app/src/processing/app/ui/SketchbookFrame.java b/app/src/processing/app/ui/SketchbookFrame.java index 5de001d28..771e5a1bb 100644 --- a/app/src/processing/app/ui/SketchbookFrame.java +++ b/app/src/processing/app/ui/SketchbookFrame.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2013-19 The Processing Foundation + Copyright (c) 2013-22 The Processing Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,20 +22,10 @@ package processing.app.ui; -import java.awt.Color; -import java.awt.EventQueue; -import java.awt.Point; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; +import java.awt.*; +import java.awt.event.*; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTree; +import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeModel; @@ -43,26 +33,56 @@ import javax.swing.tree.TreeSelectionModel; import processing.app.Base; import processing.app.Language; -import processing.app.Mode; import processing.app.Platform; import processing.app.SketchReference; public class SketchbookFrame extends JFrame { protected Base base; - protected Mode mode; - public SketchbookFrame(final Base base, final Mode mode) { + public SketchbookFrame(final Base base) { super(Language.text("sketchbook")); this.base = base; - this.mode = mode; final ActionListener listener = e -> setVisible(false); Toolkit.registerWindowCloseKeys(getRootPane(), listener); Toolkit.setIcon(this); - final JTree tree = new JTree(mode.buildSketchbookTree()); + Container pane = getContentPane(); + pane.setLayout(new BorderLayout()); + + updateCenterPanel(); + + Container buttons = Box.createHorizontalBox(); + + JButton addButton = new JButton("Show Folder"); + addButton.addActionListener(e -> Platform.openFolder(Base.getSketchbookFolder())); + buttons.add(Box.createHorizontalGlue()); + buttons.add(addButton, BorderLayout.WEST); + + JButton refreshButton = new JButton("Refresh"); + refreshButton.addActionListener(e -> base.rebuildSketchbook()); + buttons.add(refreshButton, BorderLayout.EAST); + buttons.add(Box.createHorizontalGlue()); + + final int high = addButton.getPreferredSize().height; + final int wide = 4 * Toolkit.getButtonWidth() / 3; + addButton.setPreferredSize(new Dimension(wide, high)); + refreshButton.setPreferredSize(new Dimension(wide, high)); + + JPanel buttonPanel = new JPanel(); // adds extra border + // wasn't necessary to set a border b/c JPanel adds plenty + //buttonPanel.setBorder(new EmptyBorder(3, 0, 3, 0)); + buttonPanel.add(buttons); + pane.add(buttonPanel, BorderLayout.SOUTH); + + pack(); + } + + + private JTree rebuildTree() { + final JTree tree = new JTree(base.buildSketchbookTree()); tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); tree.setShowsRootHandles(true); tree.expandRow(0); @@ -116,13 +136,23 @@ public class SketchbookFrame extends JFrame { // Special cell renderer that takes the UI zoom into account tree.setCellRenderer(new ZoomTreeCellRenderer()); + return tree; + } + + + private void updateCenterPanel() { + JTree tree = rebuildTree(); + Container panel; + // Check whether sketchbook is empty or not TreeModel treeModel = tree.getModel(); if (treeModel.getChildCount(treeModel.getRoot()) != 0) { JScrollPane treePane = new JScrollPane(tree); treePane.setPreferredSize(Toolkit.zoom(250, 450)); treePane.setBorder(new EmptyBorder(0, 0, 0, 0)); - getContentPane().add(treePane); + + //getContentPane().add(treePane); + panel = treePane; } else { JPanel emptyPanel = new JPanel(); @@ -133,10 +163,27 @@ public class SketchbookFrame extends JFrame { emptyLabel.setForeground(Color.GRAY); emptyPanel.add(emptyLabel); - setContentPane(emptyPanel); + //setContentPane(emptyPanel); + panel = emptyPanel; } - pack(); + Container pane = getContentPane(); + //pane.setLayout(new BorderLayout()); + BorderLayout layout = (BorderLayout) pane.getLayout(); + Component comp = layout.getLayoutComponent(BorderLayout.CENTER); + if (comp != null) { + pane.remove(comp); + } + pane.add(panel, BorderLayout.CENTER); + } + + + public void rebuild() { + updateCenterPanel(); + // After replacing the tree/panel, this calls the layout manager, + // otherwise it'll just leave a frozen-looking component until + // the window is closed and re-opened. + getContentPane().validate(); } diff --git a/todo.txt b/todo.txt index 3ac9b701a..3a134d2fb 100755 --- a/todo.txt +++ b/todo.txt @@ -46,6 +46,9 @@ X Problem with function size(int arg, int arg) in Class X https://github.com/processing/processing4/issues/317 X Add support for multi-line string text blocks X https://github.com/processing/processing4/issues/371 +X fullScreen() when specifying the display number was broken +X https://github.com/processing/processing4/pull/392 +X https://github.com/processing/processing4/issues/352 previous releases X need icons for .pde, .pdex, .pdez @@ -63,12 +66,17 @@ o ignore-tools in build.xml not being called for some reason o when variables used in size(), getting exceptions instead of any warning o https://github.com/processing/processing/issues/3311 +sketchbook window +X refresh option for sketchbook (bottom of window) +X add "Show Folder" entry to sketchbook window +X move sketchbook frame code to Base instead of Mode +X it was being called once for each Mode, but doesn't vary on per-Mode basis + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . class -_ refresh option for sketchbook (bottom of window) _ make sure pdex/pdez files working, also on Windows