building blocks

This commit is contained in:
bancika
2017-01-12 15:50:54 +01:00
parent c64c9fb5b2
commit 0555d4b86e
18 changed files with 290 additions and 63 deletions
@@ -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;
Binary file not shown.

After

Width:  |  Height:  |  Size: 929 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

@@ -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 {
@@ -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);
@@ -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
@@ -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);
@@ -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<String> recentComponents;
private List<String> blocks;
private IPlugInPort plugInPort;
@@ -96,15 +101,35 @@ public class TreePanel extends JPanel {
@Override
public void valueChanged(String key, Object value) {
List<String> newComponents = (List<String>) value;
if (!new HashSet<String>(newComponents).equals(new HashSet<String>(TreePanel.this.recentComponents))) {
LOG.info("Detected change");
refreshRecentComponentsToolbar(newComponents);
if (newComponents != null
&& !new HashSet<String>(newComponents).equals(new HashSet<String>(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<String>(newComponents);
}
});
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.BLOCKS_KEY, new IConfigListener() {
@SuppressWarnings("unchecked")
@Override
public void valueChanged(String key, Object value) {
Map<String, Collection<IDIYComponent<?>>> newBlocks = (Map<String, Collection<IDIYComponent<?>>>) value;
if (newBlocks != null) {
List<String> blockNames = new ArrayList<String>(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<String> recent =
(List<String>) ConfigurationManager.getInstance().readObject(IPlugInPort.RECENT_COMPONENTS_KEY, null);
if (recent != null) {
this.recentComponents = new ArrayList<String>(recent);
refreshRecentComponentsToolbar(recent);
refreshRecentComponents(recent);
} else {
this.recentComponents = new ArrayList<String>();
}
@@ -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<String, Collection<IDIYComponent<?>>> newBlocks =
(Map<String, Collection<IDIYComponent<?>>>) ConfigurationManager.getInstance().readObject(
IPlugInPort.BLOCKS_KEY, null);
if (newBlocks != null) {
List<String> blockNames = new ArrayList<String>(newBlocks.keySet());
Collections.sort(blockNames);
refreshBlocks(blockNames);
this.blocks = blockNames;
} else {
this.blocks = new ArrayList<String>();
}
}
return this.blocksNode;
}
@SuppressWarnings("unchecked")
private void refreshRecentComponentsToolbar(List<String> recentComponentClassList) {
private void refreshRecentComponents(List<String> recentComponentClassList) {
getRecentNode().removeAllChildren();
for (String componentClassName : recentComponentClassList) {
ComponentType componentType;
final ComponentType componentType;
try {
componentType =
ComponentProcessor.getInstance().extractComponentTypeFrom(
(Class<? extends IDIYComponent<?>>) 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<String> 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<String, List<ComponentType>> componentTypes = plugInPort.getComponentTypes();
List<String> categories = new ArrayList<String>(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("<html><b>" + type.getComponentType().getName() + "</b><br>"
+ type.getComponentType().getDescription() + "<br>Author: " + type.getComponentType().getAuthor()
setToolTipText("<html><b>" + payload.getComponentType().getName() + "</b><br>"
+ payload.getComponentType().getDescription() + "<br>Author: " + payload.getComponentType().getAuthor()
+ "<br><br>Left click to instantiate this component, right click for more options" + "</html>");
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();