diff --git a/diylc/diylc-core/src/org/diylc/common/BuildingBlock.java b/diylc/diylc-core/src/org/diylc/common/BuildingBlock.java new file mode 100644 index 00000000..20ddfde4 --- /dev/null +++ b/diylc/diylc-core/src/org/diylc/common/BuildingBlock.java @@ -0,0 +1,38 @@ +package org.diylc.common; + +import java.util.Collection; + +import org.diylc.core.IDIYComponent; + +public class BuildingBlock { + + private String name; + private Collection> components; + + public BuildingBlock(String name, Collection> components) { + super(); + this.name = name; + this.components = components; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Collection> getComponents() { + return components; + } + + public void setComponents(Collection> components) { + this.components = components; + } + + @Override + public String toString() { + return name; + } +} diff --git a/diylc/diylc-core/src/org/diylc/common/IBlockProcessor.java b/diylc/diylc-core/src/org/diylc/common/IBlockProcessor.java new file mode 100644 index 00000000..b50e5d90 --- /dev/null +++ b/diylc/diylc-core/src/org/diylc/common/IBlockProcessor.java @@ -0,0 +1,24 @@ +package org.diylc.common; + +public interface IBlockProcessor { + + public static final String BLOCKS_KEY = "buildingBlocks"; + + void saveSelectionAsBlock(String blockName); + + void loadBlock(String blockName) throws InvalidBlockException; + + void deleteBlock(String blockName); + + public class BlockAlreadyExistsException extends Exception { + + private static final long serialVersionUID = 1L; + + } + + public class InvalidBlockException extends Exception { + + private static final long serialVersionUID = 1L; + + } +} diff --git a/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java b/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java index 3e9e7594..c3098c9d 100644 --- a/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java +++ b/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java @@ -5,6 +5,7 @@ import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; import java.awt.geom.Point2D; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; @@ -29,7 +30,7 @@ import org.diylc.core.Theme; * @see IMessageListener * @see EventType */ -public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyProcessor, ITemplateProcessor { +public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyProcessor, ITemplateProcessor, IBlockProcessor { public static final String ANTI_ALIASING_KEY = "antiAliasing"; public static final String HI_QUALITY_RENDER_KEY = "hiQualityRender"; @@ -178,7 +179,7 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP * * @param components */ - void pasteComponents(List> components); + void pasteComponents(Collection> components); /** * Deletes all the selected components from the project. diff --git a/diylc/diylc-core/src/org/diylc/presenter/InstantiationManager.java b/diylc/diylc-core/src/org/diylc/presenter/InstantiationManager.java index 836113ff..70ec0dad 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/InstantiationManager.java +++ b/diylc/diylc-core/src/org/diylc/presenter/InstantiationManager.java @@ -4,6 +4,7 @@ import java.awt.Point; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -110,7 +111,7 @@ public class InstantiationManager { return changeMade; } - public void pasteComponents(List> components, Point scaledPoint, boolean snapToGrid, Size gridSpacing) { + public void pasteComponents(Collection> components, Point scaledPoint, boolean snapToGrid, Size gridSpacing) { // Adjust location of components so they are centered under the mouse // cursor int minX = Integer.MAX_VALUE; diff --git a/diylc/diylc-core/src/org/diylc/presenter/Presenter.java b/diylc/diylc-core/src/org/diylc/presenter/Presenter.java index f82c1109..d9edb514 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/Presenter.java +++ b/diylc/diylc-core/src/org/diylc/presenter/Presenter.java @@ -1202,7 +1202,7 @@ public class Presenter implements IPlugInPort { if (view.showConfirmDialog("Selection contains components that cannot be mirrored. Do you want to exclude them?", "Mirror Selection", IView.YES_NO_OPTION, IView.QUESTION_MESSAGE) != IView.YES_OPTION) return; - + if (changesCircuit) if (view.showConfirmDialog("Mirroring operation will change the circuit. Do you want to continue?", "Mirror Selection", IView.YES_NO_OPTION, IView.QUESTION_MESSAGE) != IView.YES_OPTION) @@ -1296,7 +1296,7 @@ public class Presenter implements IPlugInPort { } @Override - public void pasteComponents(List> components) { + public void pasteComponents(Collection> components) { LOG.info(String.format("pasteComponents(%s)", components)); instantiationManager.pasteComponents(components, this.previousScaledPoint, isSnapToGrid(), currentProject.getGridSpacing()); @@ -1969,7 +1969,7 @@ public class Presenter implements IPlugInPort { for (IDIYComponent component : this.selectedComponents) { try { drawingManager.invalidateComponent(component); -// this.instantiationManager.loadComponentShapeFromTemplate(component, template); + // this.instantiationManager.loadComponentShapeFromTemplate(component, template); this.instantiationManager.fillWithDefaultProperties(component, template); } catch (Exception e) { LOG.warn("Could not apply templates to " + component.getName(), e); @@ -2050,4 +2050,47 @@ public class Presenter implements IPlugInPort { return point == null ? null : new Point((int) (point.x / drawingManager.getZoomLevel()), (int) (point.y / drawingManager.getZoomLevel())); } + + @SuppressWarnings("unchecked") + @Override + public void saveSelectionAsBlock(String blockName) { + Map>> blocks = + (Map>>) ConfigurationManager.getInstance().readObject(BLOCKS_KEY, null); + if (blocks == null) + blocks = new HashMap>>(); + blocks.put(blockName, this.selectedComponents); + ConfigurationManager.getInstance().writeValue(BLOCKS_KEY, blocks); + } + + @SuppressWarnings("unchecked") + @Override + public void loadBlock(String blockName) throws InvalidBlockException { + Map>> blocks = + (Map>>) ConfigurationManager.getInstance().readObject(BLOCKS_KEY, null); + if (blocks != null) { + Collection> components = blocks.get(blockName); + if (components == null) + throw new InvalidBlockException(); + List> clones = new ArrayList>(); + for (IDIYComponent c : components) + try { + clones.add(c.clone()); + } catch (CloneNotSupportedException e) { + LOG.error("Could not clone component: " + c); + } + pasteComponents(clones); + } else + throw new InvalidBlockException(); + } + + @SuppressWarnings("unchecked") + @Override + public void deleteBlock(String blockName) { + Map>> blocks = + (Map>>) ConfigurationManager.getInstance().readObject(BLOCKS_KEY, null); + if (blocks != null) { + blocks.remove(blockName); + ConfigurationManager.getInstance().writeValue(BLOCKS_KEY, blocks); + } + } } diff --git a/diylc/diylc-library/lib/diylc-core.jar b/diylc/diylc-library/lib/diylc-core.jar index 8a7d81ee..c3594e48 100644 Binary files a/diylc/diylc-library/lib/diylc-core.jar and b/diylc/diylc-library/lib/diylc-core.jar differ diff --git a/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java b/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java index 3834a1f7..9d092449 100644 --- a/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java +++ b/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java @@ -35,7 +35,6 @@ public class TubeSocket extends AbstractTransparentComponent { private static final long serialVersionUID = 1L; private static Color BODY_COLOR = Color.decode("#F7F7EF"); -// private static Color BORDER_COLOR = Color.decode("#8E8E38"); public static Color PIN_COLOR = Color.decode("#00B2EE"); public static Color PIN_BORDER_COLOR = PIN_COLOR.darker(); public static Size PIN_SIZE = new Size(1d, SizeUnit.mm); @@ -44,6 +43,7 @@ public class TubeSocket extends AbstractTransparentComponent { private Base base = Base.B9A; private String type = ""; + @Deprecated private Orientation orientation; // private Mount mount = Mount.CHASSIS; private int angle; @@ -69,18 +69,6 @@ public class TubeSocket extends AbstractTransparentComponent { // Reset body shape body = null; } -// -// @EditableProperty -// public Orientation getOrientation() { -// return orientation; -// } -// -// public void setOrientation(Orientation orientation) { -// this.orientation = orientation; -// updateControlPoints(); -// // Reset body shape -// body = null; -// } @EditableProperty @SuppressWarnings("incomplete-switch") diff --git a/diylc/diylc-swing/lib/diylc-core.jar b/diylc/diylc-swing/lib/diylc-core.jar index 8a7d81ee..c3594e48 100644 Binary files a/diylc/diylc-swing/lib/diylc-core.jar and b/diylc/diylc-swing/lib/diylc-core.jar differ diff --git a/diylc/diylc-swing/src/org/diylc/images/IconLoader.java b/diylc/diylc-swing/src/org/diylc/images/IconLoader.java index 42f35296..f877b576 100644 --- a/diylc/diylc-swing/src/org/diylc/images/IconLoader.java +++ b/diylc/diylc-swing/src/org/diylc/images/IconLoader.java @@ -38,7 +38,8 @@ public enum IconLoader { "cloud_wait.png"), Spinning("spinning.gif"), Megaphone("megaphone.png"), Download("download.png"), Eye("eye.png"), Messages( "messages.png"), SearchBox("search-box.png"), Screwdriver("screwdriver.png"), Hammer("hammer.png"), FlipHorizontal( "flip_horizontal.png"), FlipVertical("flip_vertical.png"), MagicWand("magic_wand.png"), PinGrey("pin_grey.png"), PinGreen( - "pin_green.png"); + "pin_green.png"), CoffeebeanEdit("coffeebean_edit.png"), ApplicationEdit("application_edit.png"), ComponentAdd( + "component_add.png"); protected String name; diff --git a/diylc/diylc-swing/src/org/diylc/images/application_edit.png b/diylc/diylc-swing/src/org/diylc/images/application_edit.png new file mode 100644 index 00000000..08787c8f Binary files /dev/null and b/diylc/diylc-swing/src/org/diylc/images/application_edit.png differ diff --git a/diylc/diylc-swing/src/org/diylc/images/coffeebean_edit.png b/diylc/diylc-swing/src/org/diylc/images/coffeebean_edit.png new file mode 100644 index 00000000..7a714cdf Binary files /dev/null and b/diylc/diylc-swing/src/org/diylc/images/coffeebean_edit.png differ diff --git a/diylc/diylc-swing/src/org/diylc/images/component_add.png b/diylc/diylc-swing/src/org/diylc/images/component_add.png new file mode 100644 index 00000000..f41439f7 Binary files /dev/null and b/diylc/diylc-swing/src/org/diylc/images/component_add.png differ diff --git a/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java b/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java index e53265bc..6d29f8c6 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java +++ b/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java @@ -136,6 +136,10 @@ public class ActionFactory { public SaveAsTemplateAction createSaveAsTemplateAction(IPlugInPort plugInPort) { return new SaveAsTemplateAction(plugInPort); } + + public SaveAsBlockAction createSaveAsBlockAction(IPlugInPort plugInPort) { + return new SaveAsBlockAction(plugInPort); + } public ExpandSelectionAction createExpandSelectionAction(IPlugInPort plugInPort, ExpansionMode expansionMode) { return new ExpandSelectionAction(plugInPort, expansionMode); @@ -863,6 +867,30 @@ public class ActionFactory { } } } + + public static class SaveAsBlockAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public SaveAsBlockAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Save as Building Block"); + putValue(AbstractAction.SMALL_ICON, IconLoader.ComponentAdd.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Save as building block triggered"); + String templateName = + JOptionPane.showInputDialog(null, "Block name:", "Save as Building Block", JOptionPane.PLAIN_MESSAGE); + if (templateName != null && !templateName.trim().isEmpty()) { + plugInPort.saveSelectionAsBlock(templateName); + } + } + } public static class ExpandSelectionAction extends AbstractAction { diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/canvas/CanvasPlugin.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/canvas/CanvasPlugin.java index 669d94f1..60d064b7 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/plugins/canvas/CanvasPlugin.java +++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/canvas/CanvasPlugin.java @@ -65,6 +65,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { private ActionFactory.EditSelectionAction editSelectionAction; private ActionFactory.DeleteSelectionAction deleteSelectionAction; private ActionFactory.SaveAsTemplateAction saveAsTemplateAction; + private ActionFactory.SaveAsBlockAction saveAsBlockAction; private ActionFactory.GroupAction groupAction; private ActionFactory.UngroupAction ungroupAction; private ActionFactory.SendToBackAction sendToBackAction; @@ -154,6 +155,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { getMirrorVerticallyAction().setEnabled(enabled); getSaveAsTemplateAction().setEnabled(plugInPort.getSelectedComponents().size() == 1); + getSaveAsBlockAction().setEnabled(plugInPort.getSelectedComponents().size() > 1); showPopupAt(e.getX(), e.getY()); } @@ -265,6 +267,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { popupMenu.add(getTransformMenu()); popupMenu.add(getSaveAsTemplateAction()); popupMenu.add(getApplyTemplateMenu()); + popupMenu.add(getSaveAsBlockAction()); popupMenu.add(getExpandMenu()); popupMenu.addSeparator(); popupMenu.add(ActionFactory.getInstance().createEditProjectAction(plugInPort)); @@ -439,6 +442,13 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { return saveAsTemplateAction; } + public ActionFactory.SaveAsBlockAction getSaveAsBlockAction() { + if (saveAsBlockAction == null) { + saveAsBlockAction = ActionFactory.getInstance().createSaveAsBlockAction(plugInPort); + } + return saveAsBlockAction; + } + public ActionFactory.GroupAction getGroupAction() { if (groupAction == null) { groupAction = ActionFactory.getInstance().createGroupAction(plugInPort); diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/edit/EditMenuPlugin.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/edit/EditMenuPlugin.java index fb977ba5..3046bcff 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/plugins/edit/EditMenuPlugin.java +++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/edit/EditMenuPlugin.java @@ -47,6 +47,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { private ActionFactory.ExpandSelectionAction expandSelectionImmediateAction; private ActionFactory.ExpandSelectionAction expandSelectionSameTypeAction; private ActionFactory.SaveAsTemplateAction saveAsTemplateAction; + private ActionFactory.SaveAsBlockAction saveAsBlockAction; private ActionFactory.RotateSelectionAction rotateClockwiseAction; private ActionFactory.RotateSelectionAction rotateCounterClockwiseAction; private ActionFactory.MirrorSelectionAction mirrorHorizontallyAction; @@ -187,6 +188,13 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { } return saveAsTemplateAction; } + + public ActionFactory.SaveAsBlockAction getSaveAsBlockAction() { + if (saveAsBlockAction == null) { + saveAsBlockAction = ActionFactory.getInstance().createSaveAsBlockAction(plugInPort); + } + return saveAsBlockAction; + } public ActionFactory.RotateSelectionAction getRotateClockwiseAction() { if (rotateClockwiseAction == null) { @@ -306,6 +314,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { getMirrorHorizontallyAction().setEnabled(enabled); getMirrorVerticallyAction().setEnabled(enabled); getSaveAsTemplateAction().setEnabled(enabled); + getSaveAsBlockAction().setEnabled(enabled); } // ClipboardOwner diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/help/HelpMenuPlugin.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/help/HelpMenuPlugin.java index e0dbd243..cdc9de9f 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/plugins/help/HelpMenuPlugin.java +++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/help/HelpMenuPlugin.java @@ -39,9 +39,9 @@ public class HelpMenuPlugin implements IPlugIn { public HelpMenuPlugin(ISwingUI swingUI) { swingUI.injectMenuAction(new NavigateURLAction("User Manual", IconLoader.Manual.getIcon(), MANUAL_URL), HELP_TITLE); swingUI.injectMenuAction(new NavigateURLAction("FAQ", IconLoader.Faq.getIcon(), FAQ_URL), HELP_TITLE); - swingUI.injectMenuAction(new NavigateURLAction("Component API", IconLoader.Component.getIcon(), COMPONENT_URL), + swingUI.injectMenuAction(new NavigateURLAction("Component API", IconLoader.CoffeebeanEdit.getIcon(), COMPONENT_URL), HELP_TITLE); - swingUI.injectMenuAction(new NavigateURLAction("Plugin API", IconLoader.Plugin.getIcon(), PLUGIN_URL), HELP_TITLE); + swingUI.injectMenuAction(new NavigateURLAction("Plugin API", IconLoader.ApplicationEdit.getIcon(), PLUGIN_URL), HELP_TITLE); swingUI.injectMenuAction(new NavigateURLAction("Submit a Bug", IconLoader.Bug.getIcon(), BUG_URL), HELP_TITLE); swingUI.injectMenuAction(null, HELP_TITLE); swingUI.injectMenuAction(new NavigateURLAction("Donate", IconLoader.Donate.getIcon(), DONATE_URL), HELP_TITLE); diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/tree/TreePanel.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/tree/TreePanel.java index 644d4738..c6f823aa 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/plugins/tree/TreePanel.java +++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/tree/TreePanel.java @@ -13,7 +13,9 @@ import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -43,6 +45,7 @@ import org.apache.log4j.Logger; import org.diylc.appframework.miscutils.ConfigurationManager; import org.diylc.appframework.miscutils.IConfigListener; import org.diylc.common.ComponentType; +import org.diylc.common.IBlockProcessor.InvalidBlockException; import org.diylc.common.IPlugInPort; import org.diylc.core.IDIYComponent; import org.diylc.core.Template; @@ -61,7 +64,9 @@ public class TreePanel extends JPanel { private JScrollPane treeScroll; private JTextField searchField; private DefaultMutableTreeNode recentNode; + private DefaultMutableTreeNode blocksNode; private List recentComponents; + private List blocks; private IPlugInPort plugInPort; @@ -96,15 +101,35 @@ public class TreePanel extends JPanel { @Override public void valueChanged(String key, Object value) { List newComponents = (List) value; - if (!new HashSet(newComponents).equals(new HashSet(TreePanel.this.recentComponents))) { - LOG.info("Detected change"); - refreshRecentComponentsToolbar(newComponents); + if (newComponents != null + && !new HashSet(newComponents).equals(new HashSet(TreePanel.this.recentComponents))) { + LOG.info("Detected recent component change"); + refreshRecentComponents(newComponents); } else - LOG.info("Detected no change"); + LOG.info("Detected no recent component change"); TreePanel.this.recentComponents = new ArrayList(newComponents); } }); + ConfigurationManager.getInstance().addConfigListener(IPlugInPort.BLOCKS_KEY, new IConfigListener() { + + @SuppressWarnings("unchecked") + @Override + public void valueChanged(String key, Object value) { + Map>> newBlocks = (Map>>) value; + if (newBlocks != null) { + List blockNames = new ArrayList(newBlocks.keySet()); + Collections.sort(blockNames); + if (!blockNames.equals(TreePanel.this.blocks)) { + LOG.info("Detected block change"); + refreshBlocks(blockNames); + } else + LOG.info("Detected no block change"); + } else + LOG.info("Detected no block change"); + } + }); + getTree().expandRow(0); } @@ -118,13 +143,13 @@ public class TreePanel extends JPanel { public DefaultMutableTreeNode getRecentNode() { if (this.recentNode == null) { - this.recentNode = new DefaultMutableTreeNode(new Payload("(Recently Used)"), true); + this.recentNode = new DefaultMutableTreeNode(new Payload("(Recently Used)", null), true); @SuppressWarnings("unchecked") List recent = (List) ConfigurationManager.getInstance().readObject(IPlugInPort.RECENT_COMPONENTS_KEY, null); if (recent != null) { this.recentComponents = new ArrayList(recent); - refreshRecentComponentsToolbar(recent); + refreshRecentComponents(recent); } else { this.recentComponents = new ArrayList(); } @@ -132,16 +157,41 @@ public class TreePanel extends JPanel { return this.recentNode; } + public DefaultMutableTreeNode getBlocksNode() { + if (this.blocksNode == null) { + this.blocksNode = new DefaultMutableTreeNode(new Payload("(Building Blocks)", null), true); + @SuppressWarnings("unchecked") + Map>> newBlocks = + (Map>>) ConfigurationManager.getInstance().readObject( + IPlugInPort.BLOCKS_KEY, null); + if (newBlocks != null) { + List blockNames = new ArrayList(newBlocks.keySet()); + Collections.sort(blockNames); + refreshBlocks(blockNames); + this.blocks = blockNames; + } else { + this.blocks = new ArrayList(); + } + } + return this.blocksNode; + } + @SuppressWarnings("unchecked") - private void refreshRecentComponentsToolbar(List recentComponentClassList) { + private void refreshRecentComponents(List recentComponentClassList) { getRecentNode().removeAllChildren(); for (String componentClassName : recentComponentClassList) { - ComponentType componentType; + final ComponentType componentType; try { componentType = ComponentProcessor.getInstance().extractComponentTypeFrom( (Class>) Class.forName(componentClassName)); - Payload payload = new Payload(componentType); + Payload payload = new Payload(componentType, new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + plugInPort.setNewComponentTypeSlot(componentType, null); + } + }); final DefaultMutableTreeNode componentNode = new DefaultMutableTreeNode(payload, false); String text = getSearchField().getText(); boolean visible = @@ -157,18 +207,51 @@ public class TreePanel extends JPanel { getTreeModel().nodeStructureChanged(getRecentNode()); } + private void refreshBlocks(List blocks) { + getBlocksNode().removeAllChildren(); + for (final String block : blocks) { + Payload payload = new Payload(block, new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + if (SwingUtilities.isLeftMouseButton(e)) { + try { + plugInPort.loadBlock(block); + } catch (InvalidBlockException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + } + }); + final DefaultMutableTreeNode componentNode = new DefaultMutableTreeNode(payload, false); + String text = getSearchField().getText(); + boolean visible = text.trim().length() == 0 || block.toLowerCase().contains(text.toLowerCase()); + payload.setVisible(visible); + getBlocksNode().add(componentNode); + } + getTreeModel().nodeStructureChanged(getBlocksNode()); + } + public DefaultTreeModel getTreeModel() { if (treeModel == null) { final DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Components", true); rootNode.add(getRecentNode()); + rootNode.add(getBlocksNode()); Map> componentTypes = plugInPort.getComponentTypes(); List categories = new ArrayList(componentTypes.keySet()); Collections.sort(categories); for (String category : categories) { - final DefaultMutableTreeNode categoryNode = new DefaultMutableTreeNode(new Payload(category)); + final DefaultMutableTreeNode categoryNode = new DefaultMutableTreeNode(new Payload(category, null)); rootNode.add(categoryNode); - for (ComponentType type : componentTypes.get(category)) { - final DefaultMutableTreeNode componentNode = new DefaultMutableTreeNode(new Payload(type), false); + for (final ComponentType type : componentTypes.get(category)) { + final DefaultMutableTreeNode componentNode = new DefaultMutableTreeNode(new Payload(type, new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + plugInPort.setNewComponentTypeSlot(type, null); + } + }), false); categoryNode.add(componentNode); } } @@ -184,21 +267,6 @@ public class TreePanel extends JPanel { tree.setCellRenderer(new ComponentCellRenderer()); tree.setRowHeight(0); ToolTipManager.sharedInstance().registerComponent(tree); - // tree.addTreeSelectionListener(new TreeSelectionListener() { - // - // @Override - // public void valueChanged(TreeSelectionEvent e) { - // Object c = e.getPath().getLastPathComponent(); - // if (c != null && c.getClass().equals(DefaultMutableTreeNode.class)) { - // DefaultMutableTreeNode node = (DefaultMutableTreeNode) c; - // Object obj = node.getUserObject(); - // if (obj != null && obj.getClass().equals(Payload.class)) { - // Payload payload = (Payload) obj; - // plugInPort.setNewComponentTypeSlot(payload.getComponentType(), null); - // } - // } - // } - // }); tree.addMouseListener(new MouseAdapter() { @@ -208,8 +276,8 @@ public class TreePanel extends JPanel { DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); if (node != null && node.getUserObject() != null) { Payload payload = (Payload) node.getUserObject(); - if (payload.getComponentType() != null) { - plugInPort.setNewComponentTypeSlot(payload.getComponentType(), null); + if (payload.getClickListener() != null) { + payload.getClickListener().mouseClicked(e); } } if (SwingUtilities.isRightMouseButton(e)) { @@ -326,12 +394,14 @@ public class TreePanel extends JPanel { boolean visible = false; if (text.trim().length() == 0) { visible = true; - } else { + } else if (payload.getComponentType() != null) { ComponentType type = payload.getComponentType(); visible = type.getName().toLowerCase().contains(text.toLowerCase()) || type.getDescription().toLowerCase().contains(text.toLowerCase()) || type.getCategory().toLowerCase().contains(text.toLowerCase()); + } else { + visible = payload.toString().toLowerCase().contains(text.toLowerCase()); } if (visible != payload.isVisible()) { payload.setVisible(visible); @@ -351,14 +421,14 @@ public class TreePanel extends JPanel { model.nodeStructureChanged(rootNode); } if (categoryVisible && text.trim().length() > 0) { - tree.expandPath(new TreePath(categoryNode.getPath())); + getTree().expandPath(new TreePath(categoryNode.getPath())); } } } for (int i = 0; i < model.getChildCount(rootNode); i++) { DefaultMutableTreeNode categoryNode = (DefaultMutableTreeNode) model.getChild(rootNode, i); - tree.expandPath(new TreePath(categoryNode.getPath())); + getTree().expandPath(new TreePath(categoryNode.getPath())); } } }); @@ -378,18 +448,21 @@ public class TreePanel extends JPanel { Object obj = ((DefaultMutableTreeNode) value).getUserObject(); if (obj != null && obj.getClass().equals(Payload.class)) { - Payload type = (Payload) obj; - if (type.getComponentType() == null) { - if (type.isVisible()) + Payload payload = (Payload) obj; + if (payload.getComponentType() == null) { + setToolTipText(null); + if (leaf) + setIcon(IconLoader.Component.getIcon()); + if (payload.isVisible()) setPreferredSize(new Dimension(240, 20)); else setPreferredSize(new Dimension(0, 0)); } else { - setToolTipText("" + type.getComponentType().getName() + "
" - + type.getComponentType().getDescription() + "
Author: " + type.getComponentType().getAuthor() + setToolTipText("" + payload.getComponentType().getName() + "
" + + payload.getComponentType().getDescription() + "
Author: " + payload.getComponentType().getAuthor() + "

Left click to instantiate this component, right click for more options" + ""); - setIcon(type.getComponentType().getIcon()); - if (type.isVisible()) + setIcon(payload.getComponentType().getIcon()); + if (payload.isVisible()) setPreferredSize(new Dimension(240, 32)); else setPreferredSize(new Dimension(0, 0)); @@ -404,16 +477,19 @@ public class TreePanel extends JPanel { private ComponentType componentType; private String category; private boolean isVisible; + private MouseListener clickListener; - public Payload(ComponentType componentType) { + public Payload(ComponentType componentType, MouseListener clickListener) { super(); this.componentType = componentType; + this.clickListener = clickListener; this.isVisible = true; } - public Payload(String category) { + public Payload(String category, MouseListener clickListener) { super(); this.category = category; + this.clickListener = clickListener; this.isVisible = true; } @@ -429,6 +505,10 @@ public class TreePanel extends JPanel { this.isVisible = isVisible; } + public MouseListener getClickListener() { + return clickListener; + } + @Override public String toString() { return componentType == null ? category : componentType.getName(); diff --git a/diylc/diylc-swing/update.xml b/diylc/diylc-swing/update.xml index ce50cecd..cfa01f26 100644 --- a/diylc/diylc-swing/update.xml +++ b/diylc/diylc-swing/update.xml @@ -1554,6 +1554,10 @@ 2017-01-05 20:00:00.000 CET + + NEW_FEATURE + Ability to quickly save a group of components as a building block and use it later + NEW_FEATURE Show/hide rulers