From 0555d4b86e2a427995b93c0a2500a08b62bbde54 Mon Sep 17 00:00:00 2001 From: bancika Date: Thu, 12 Jan 2017 15:50:54 +0100 Subject: [PATCH] building blocks --- .../src/org/diylc/common/BuildingBlock.java | 38 ++++ .../src/org/diylc/common/IBlockProcessor.java | 24 +++ .../src/org/diylc/common/IPlugInPort.java | 5 +- .../diylc/presenter/InstantiationManager.java | 3 +- .../src/org/diylc/presenter/Presenter.java | 49 +++++- diylc/diylc-library/lib/diylc-core.jar | Bin 234345 -> 234345 bytes .../org/diylc/components/tube/TubeSocket.java | 14 +- diylc/diylc-swing/lib/diylc-core.jar | Bin 234345 -> 234345 bytes .../src/org/diylc/images/IconLoader.java | 3 +- .../src/org/diylc/images/application_edit.png | Bin 0 -> 929 bytes .../src/org/diylc/images/coffeebean_edit.png | Bin 0 -> 910 bytes .../src/org/diylc/images/component_add.png | Bin 0 -> 910 bytes .../src/org/diylc/swing/ActionFactory.java | 28 +++ .../swing/plugins/canvas/CanvasPlugin.java | 10 ++ .../swing/plugins/edit/EditMenuPlugin.java | 9 + .../swing/plugins/help/HelpMenuPlugin.java | 4 +- .../diylc/swing/plugins/tree/TreePanel.java | 162 +++++++++++++----- diylc/diylc-swing/update.xml | 4 + 18 files changed, 290 insertions(+), 63 deletions(-) create mode 100644 diylc/diylc-core/src/org/diylc/common/BuildingBlock.java create mode 100644 diylc/diylc-core/src/org/diylc/common/IBlockProcessor.java create mode 100644 diylc/diylc-swing/src/org/diylc/images/application_edit.png create mode 100644 diylc/diylc-swing/src/org/diylc/images/coffeebean_edit.png create mode 100644 diylc/diylc-swing/src/org/diylc/images/component_add.png 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 8a7d81ee8c5ff21ace5dac97065c7f0e1fb319f7..c3594e48f1a68dc2844567ee1083f6652d5581f5 100644 GIT binary patch delta 4061 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 G(ElGn#98J5 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 8a7d81ee8c5ff21ace5dac97065c7f0e1fb319f7..c3594e48f1a68dc2844567ee1083f6652d5581f5 100644 GIT binary patch delta 4061 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 G(ElGn#98J5 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 0000000000000000000000000000000000000000..08787c8fe22d9a82eabe898fdcf05219d1004101 GIT binary patch literal 929 zcmV;S177@zP)WdKcYATc!{L}hv)GB7YRATcsJGdMakHy|r8F)%P`khjAC000McNliru z)&&<0F(CMM0qp<)010qNS#tmY3h)2`3h)6!tTdPa000DMK}|sb0I`n?{9y$E00Q|* zL_t(|+J#eHNK;`LevW6;9c^d2O^3F&CCsqDi%2Qbum}@jN<}{ty2y*5h`@_(y6Mgf z?J|ghiijZSqAr38Li}QEH|+S8a3dcy|7FPTx095&h5y&&~V2&-1?D`#v9w zznnvd&IdxF?zFT=X>g#*(As#o3ckfn=+qWmRty{xA zkIICA8|u25*lSxM3vS*F!Bf_!0afwesB6Ze@dj(AC_ z%~m5#eck@hzzDfa|LmZ;+I`aPb`@HeWvx&>pV#2?mtkUg0Kt=IAg*qNC7VSChDaz4 z1mzY=?(Dqe3F-IyZg?Brh92VR|$ao`gunr7Y-$L(;BT1p$x8(;x^rLRO*c z2Fkq(M)=F{x~eeyDT(3dF|<2QpdwX=L?X+UmAQ)v%}TdO1&VC85??My+t>8L?O#Rx1ORE#nBUf{M@~8mg*D3{zy)bq%T17d?<-)7S5f zxl)V-Zr(pz&$U!V=M#j)KoA5nWXUjnU?~U;4i5Cs&8_K~oE(e#{mguPHdeWkQj(+b z=#rX@Xb+1YXY159co$v&9)8{I+sriLPQ`BnaaOQ_f(=B`lGg?p|Ev;Ma00000NkvXXu0mjf DJ{zT# literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7a714cdfb176570b87319e077687dd68726a5ed6 GIT binary patch literal 910 zcmV;919AL`P)WdKBJATc%|L}hv)GB7YRATl#LFgQ9eI3O!9F)%RH$o>rg000McNliru z)&&<0F)wJz9DD!(010qNS#tmY3h)2`3h)6!tTdPa000DMK}|sb0I`n?{9y$E00QPo zL_t(|+J%!_NRwe0$NxL%HVt=Vb90tuIL%aKYlMN831USll!;!6bdvC*3opA6ya?~S z?LZNN(ShhFm=)?gWUkUuGo8opQ|C^)Ii2p%^O-_~g&HMlZCsX6BvLJVy#59I+BcgMjh00WlFiz-BjMjl5*jm%;=9J&gsdnL4-B&i zr`>^wC<37ZhZnk#MuO@f@SV*4oD;#exFQkx1tp5s+(LcglHCS7>ww=MzzY54@&Yqc zDx5fXNn3i#bk-M)>YJFJSs>ZQrh_sabmsh+Hq%k1bawO?0_$P;*6EvJ;FATgyYwh8 zE=6j88v@qhSVKWk(u)p@m87oC6y#denR2wMnXz#MDL&r@@V*V`9|24$Qe3US0WIr> zfv>^O!9{f4e_$lp5rW~L)tN(T7;5U^PcTF1 zrF=5hG+@vx;hpp-~4IqpDz`vmf&nRxc(^&5s|$r=NM zN1&8o&ch;m(24`001stXbWj^lqAzV6`}BHDPCL+H8HRZ&6Yf^`yT>0o=1EAsK|ir1 zm|elzq!&Hu8swh2DA34s8JN?Epgg94!?}#k?ja6m= zgsB=n8n#jId_gZGGl-tD?HFPh#EhvJkyX=julbRkYB9PVJlgfdBvi07*qoM6N<$g7nj%?f?J) literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f41439f78a19540eb69e628fc7f4e5808b493d83 GIT binary patch literal 910 zcmV;919AL`P)WdKHUATl^0MrC3kGB7YRATcyLH8DCdG9W83F)%RHWK$ae000McNliru z)&&<0F)-!95s3f*010qNS#tmY3h)2`3h)6!tTdPa000DMK}|sb0I`n?{9y$E00QPo zL_t(|+I^E*NK{c6$G>}LbT%B9aTx|nQy~`?fcqyXaI*|2!(A9Q|6&+$Z#HUOOtJlmBj(cELd$h zSxGAH5566lW~vm#U*zoqh?$2ReJ$5vvsynctDsXI3_Ru7x<-?cJvi(_g#QH)rp^`x zAH4BDk0)d>3;?2OFhBA5gJ5xHTWUK?^E&VBwzm$IY|T0)Y#0m;I|b?%scbhXQBQ46 zWm!xC(5L~+fiUdzm|;UTASyF>Ju&;}$K7LRP!~c}9>DB%O05kw75S1vAd>LFPe}!h z=s<88E_V@3VYK+V1eSsVP^CyQY7QV{NH`ThRuu9%m;gnipz8(@oq@&}5L`wi5`&`9 zyXo#m4;6E5<-)FdTh~MIpw5z6f|*c85~>aqXQhk>Kqvz$m|$fgV4SF@Vc+V(CRj-o zvJkJh^j~?K3+B6tw_DEk(74ii^;L-+JH@lye`<3L!+qw7*Qxt^0>h zKB3V?RWR8ksb#Vqe=Hj~?MsPORfS$(Gy0^%m7Cl{=s@n7lL{juVIT$l^C*tu$8kfK z{hmU*7d}DRx&GU!)O)*|;qr~A*dVY8Kq>dboKy)hVa=VT)pfs1>RyuY>^u%E+<&j+ zyy%c26jh;XG;ebW*dNdjqv<~2wkqOALREe(E@1_j)lyu?U3T&gz4dHysqOrjA&1u( z7hWA4&&9;m*pZ-_UUC8h72cckV%?ESISpWb407*qoM6N<$f)?9@CIA2c literal 0 HcmV?d00001 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