diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/common/ISelectionProcessor.java b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/common/ISelectionProcessor.java index ae5c834a..2956baf5 100644 --- a/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/common/ISelectionProcessor.java +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/common/ISelectionProcessor.java @@ -3,6 +3,7 @@ package org.diylc.common; import java.awt.Point; import java.util.List; +import org.diylc.core.ExpansionMode; import org.diylc.core.IDIYComponent; public interface ISelectionProcessor { @@ -32,6 +33,14 @@ public interface ISelectionProcessor { */ List> findComponentsAt(Point point); + /** + * Expands the current selection to include surrounding components. + * Options are controlled with expansionMode flag. + * + * @param expansionMode + */ + void expandSelection(ExpansionMode expansionMode); + /** * Selects all components in the project. */ diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/core/ExpansionMode.java b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/core/ExpansionMode.java new file mode 100644 index 00000000..1de715af --- /dev/null +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/core/ExpansionMode.java @@ -0,0 +1,8 @@ +package org.diylc.core; + +public enum ExpansionMode { + + ALL, + SAME_TYPE, + IMMEDIATE, +} diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/presenter/Presenter.java b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/presenter/Presenter.java index 97916d44..6d81f032 100644 --- a/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/presenter/Presenter.java +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/presenter/Presenter.java @@ -37,6 +37,7 @@ import org.diylc.common.IPlugIn; import org.diylc.common.IPlugInPort; import org.diylc.common.PropertyWrapper; import org.diylc.components.connectivity.SolderPad; +import org.diylc.core.ExpansionMode; import org.diylc.core.IDIYComponent; import org.diylc.core.IView; import org.diylc.core.Project; @@ -55,7 +56,7 @@ public class Presenter implements IPlugInPort { private static final Logger LOG = Logger.getLogger(Presenter.class); - public static final VersionNumber CURRENT_VERSION = new VersionNumber(3, 2, 0); + public static final VersionNumber CURRENT_VERSION = new VersionNumber(3, 3, 0); public static final String DEFAULTS_KEY_PREFIX = "default."; public static final List> EMPTY_SELECTION = Collections.emptyList(); @@ -1078,6 +1079,7 @@ public class Presenter implements IPlugInPort { @Override public void refresh() { + LOG.info("refresh()"); messageDispatcher.dispatchMessage(EventType.REPAINT); } @@ -1093,6 +1095,7 @@ public class Presenter implements IPlugInPort { @Override public void renumberSelectedComponents(final boolean xAxisFirst) { + LOG.info("renumberSelectedComponents(" + xAxisFirst + ")"); if (getSelectedComponents().isEmpty()) { return; } @@ -1183,6 +1186,66 @@ public class Presenter implements IPlugInPort { controlPointMap.keySet()); } + @Override + public void expandSelection(ExpansionMode expansionMode) { + List> newSelection = new ArrayList>( + this.selectedComponents); + // Find control points of all selected components and all types + Set selectedNamePrefixes = new HashSet(); + if (expansionMode == ExpansionMode.SAME_TYPE) { + for (IDIYComponent component : getSelectedComponents()) { + selectedNamePrefixes.add(ComponentProcessor.getInstance().extractComponentTypeFrom( + (Class>) component.getClass()).getNamePrefix()); + } + } + // Now try to find components that intersect with at least one component + // in the pool. + for (IDIYComponent component : getCurrentProject().getComponents()) { + // Skip already selected components or ones that cannot be stuck to + // other components. + Area area = drawingManager.getComponentArea(component); + if (newSelection.contains(component) || !component.isControlPointSticky(0) || area == null) + continue; + boolean matches = false; + for (IDIYComponent selectedComponent : this.selectedComponents) { + Area selectedArea = drawingManager.getComponentArea(selectedComponent); + if (selectedArea == null) + continue; + Area intersection = new Area(area); + intersection.intersect(selectedArea); + if (!intersection.isEmpty()) { + matches = true; + break; + } + } + + if (matches) { + switch (expansionMode) { + case ALL: + case IMMEDIATE: + newSelection.add(component); + break; + case SAME_TYPE: + if (selectedNamePrefixes.contains(ComponentProcessor.getInstance() + .extractComponentTypeFrom( + (Class>) component.getClass()) + .getNamePrefix())) { + newSelection.add(component); + } + break; + } + } + } + + int oldSize = this.getSelectedComponents().size(); + updateSelection(newSelection); + // Go deeper if possible. + if (newSelection.size() > oldSize && expansionMode != ExpansionMode.IMMEDIATE) { + expandSelection(expansionMode); + } + messageDispatcher.dispatchMessage(EventType.REPAINT); + } + /** * Removes all the groups that contain at least one of the specified * components. diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/lib/diylc-core.jar b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/lib/diylc-core.jar index 1d0d7b1a..76339b12 100644 Binary files a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/lib/diylc-core.jar and b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/lib/diylc-core.jar differ diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/images/IconLoader.java b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/images/IconLoader.java index 75f1cede..f2034622 100644 --- a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/images/IconLoader.java +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/images/IconLoader.java @@ -31,7 +31,8 @@ public enum IconLoader { "donate.png"), Bug("bug.png"), IconLarge("icon_large.png"), IconMedium( "icon_medium.png"), IconSmall("icon_small.png"), DocumentEdit("document_edit.png"), EditComponent( "edit_component.png"), Size("size.png"), Front("front.png"), Back("back.png"), Pens( - "pens.png"), Sort("sort.png"), ElementsSelection("elements_selection.png"); + "pens.png"), Sort("sort.png"), ElementsSelection("elements_selection.png"), BranchAdd( + "branch_add.png"); protected String name; diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/images/branch_add.png b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/images/branch_add.png new file mode 100644 index 00000000..cd047e54 Binary files /dev/null and b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/images/branch_add.png differ diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/ActionFactory.java b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/ActionFactory.java index 3343ff89..638c3118 100644 --- a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/ActionFactory.java +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/ActionFactory.java @@ -16,6 +16,7 @@ import org.diylc.appframework.miscutils.ConfigurationManager; import org.diylc.common.IPlugInPort; import org.diylc.common.ITask; import org.diylc.common.PropertyWrapper; +import org.diylc.core.ExpansionMode; import org.diylc.core.IDIYComponent; import org.diylc.core.IView; import org.diylc.core.Theme; @@ -128,6 +129,11 @@ public class ActionFactory { return new DeleteSelectionAction(plugInPort); } + public ExpandSelectionAction createExpandSelectionAction(IPlugInPort plugInPort, + ExpansionMode expansionMode) { + return new ExpandSelectionAction(plugInPort, expansionMode); + } + public SendToBackAction createSendToBackAction(IPlugInPort plugInPort) { return new SendToBackAction(plugInPort); } @@ -142,11 +148,11 @@ public class ActionFactory { boolean defaultValue) { return new ConfigAction(plugInPort, title, configKey, defaultValue); } - + public ThemeAction createThemeAction(IPlugInPort plugInPort, Theme theme) { return new ThemeAction(plugInPort, theme); } - + public RenumberAction createRenumberAction(IPlugInPort plugInPort, boolean xAxisFirst) { return new RenumberAction(plugInPort, xAxisFirst); } @@ -756,6 +762,40 @@ public class ActionFactory { } } + public static class ExpandSelectionAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private ExpansionMode expansionMode; + + public ExpandSelectionAction(IPlugInPort plugInPort, ExpansionMode expansionMode) { + super(); + this.plugInPort = plugInPort; + this.expansionMode = expansionMode; + switch (expansionMode) { + case ALL: + putValue(AbstractAction.NAME, "All Connected"); + break; + case IMMEDIATE: + putValue(AbstractAction.NAME, "Immediate Only"); + break; + case SAME_TYPE: + putValue(AbstractAction.NAME, "Same Type Only"); + break; + + default: + break; + } + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Expand Selection triggered: " + expansionMode); + plugInPort.expandSelection(expansionMode); + } + } + public static class SendToBackAction extends AbstractAction { private static final long serialVersionUID = 1L; @@ -846,7 +886,7 @@ public class ActionFactory { plugInPort.setSelectedTheme(theme); } } - + public static class RenumberAction extends AbstractAction { private static final long serialVersionUID = 1L; diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/plugins/canvas/CanvasPlugin.java b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/plugins/canvas/CanvasPlugin.java index d75bb0db..d2ad0de6 100644 --- a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/plugins/canvas/CanvasPlugin.java +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/plugins/canvas/CanvasPlugin.java @@ -29,6 +29,7 @@ import org.diylc.common.BadPositionException; import org.diylc.common.EventType; import org.diylc.common.IPlugIn; import org.diylc.common.IPlugInPort; +import org.diylc.core.ExpansionMode; import org.diylc.core.IDIYComponent; import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; @@ -49,6 +50,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { private CanvasPanel canvasPanel; private JPopupMenu popupMenu; private JMenu selectionMenu; + private JMenu expandMenu; private ActionFactory.CutAction cutAction; private ActionFactory.CopyAction copyAction; @@ -59,6 +61,9 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { private ActionFactory.UngroupAction ungroupAction; private ActionFactory.SendToBackAction sendToBackAction; private ActionFactory.BringToFrontAction bringToFrontAction; + private ActionFactory.ExpandSelectionAction expandSelectionAllAction; + private ActionFactory.ExpandSelectionAction expandSelectionImmediateAction; + private ActionFactory.ExpandSelectionAction expandSelectionSameTypeAction; private IPlugInPort plugInPort; private ISwingUI swingUI; @@ -104,6 +109,9 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { } getEditSelectionAction().setEnabled(enabled); getDeleteSelectionAction().setEnabled(enabled); + getExpandSelectionAllAction().setEnabled(enabled); + getExpandSelectionImmediateAction().setEnabled(enabled); + getExpandSelectionSameTypeAction().setEnabled(enabled); getGroupAction().setEnabled(enabled); getUngroupAction().setEnabled(enabled); getSendToBackAction().setEnabled(enabled); @@ -193,6 +201,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { popupMenu.add(getUngroupAction()); popupMenu.add(getSendToBackAction()); popupMenu.add(getBringToFrontAction()); + popupMenu.add(getExpandMenu()); popupMenu.addSeparator(); popupMenu.add(ActionFactory.getInstance().createEditProjectAction(plugInPort)); } @@ -207,6 +216,17 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { return selectionMenu; } + public JMenu getExpandMenu() { + if (expandMenu == null) { + expandMenu = new JMenu("Expand Selection"); + expandMenu.setIcon(IconLoader.BranchAdd.getIcon()); + expandMenu.add(getExpandSelectionAllAction()); + expandMenu.add(getExpandSelectionImmediateAction()); + expandMenu.add(getExpandSelectionSameTypeAction()); + } + return expandMenu; + } + private void updateSelectionMenu(int x, int y) { getSelectionMenu().removeAll(); for (IDIYComponent component : plugInPort.findComponentsAt(new Point(x, y))) { @@ -290,6 +310,30 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { return bringToFrontAction; } + public ActionFactory.ExpandSelectionAction getExpandSelectionAllAction() { + if (expandSelectionAllAction == null) { + expandSelectionAllAction = ActionFactory.getInstance().createExpandSelectionAction( + plugInPort, ExpansionMode.ALL); + } + return expandSelectionAllAction; + } + + public ActionFactory.ExpandSelectionAction getExpandSelectionImmediateAction() { + if (expandSelectionImmediateAction == null) { + expandSelectionImmediateAction = ActionFactory.getInstance() + .createExpandSelectionAction(plugInPort, ExpansionMode.IMMEDIATE); + } + return expandSelectionImmediateAction; + } + + public ActionFactory.ExpandSelectionAction getExpandSelectionSameTypeAction() { + if (expandSelectionSameTypeAction == null) { + expandSelectionSameTypeAction = ActionFactory.getInstance() + .createExpandSelectionAction(plugInPort, ExpansionMode.SAME_TYPE); + } + return expandSelectionSameTypeAction; + } + @Override public EnumSet getSubscribedEventTypes() { return EnumSet.of(EventType.PROJECT_LOADED, EventType.ZOOM_CHANGED, EventType.REPAINT); diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/plugins/edit/EditMenuPlugin.java b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/plugins/edit/EditMenuPlugin.java index 6d981954..3f06e6ca 100644 --- a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/plugins/edit/EditMenuPlugin.java +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/plugins/edit/EditMenuPlugin.java @@ -13,6 +13,7 @@ import org.diylc.appframework.undo.UndoHandler; import org.diylc.common.EventType; import org.diylc.common.IPlugIn; import org.diylc.common.IPlugInPort; +import org.diylc.core.ExpansionMode; import org.diylc.core.Project; import org.diylc.images.IconLoader; import org.diylc.swing.ActionFactory; @@ -22,6 +23,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { private static final String EDIT_TITLE = "Edit"; private static final String RENUMBER_TITLE = "Renumber Selection"; + private static final String EXPAND_TITLE = "Expand Selection"; private IPlugInPort plugInPort; private ISwingUI swingUI; @@ -39,6 +41,9 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { private ActionFactory.BringToFrontAction bringToFrontAction; private ActionFactory.RenumberAction renumberXAxisAction; private ActionFactory.RenumberAction renumberYAxisAction; + private ActionFactory.ExpandSelectionAction expandSelectionAllAction; + private ActionFactory.ExpandSelectionAction expandSelectionImmediateAction; + private ActionFactory.ExpandSelectionAction expandSelectionSameTypeAction; private UndoHandler undoHandler; @@ -149,6 +154,30 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { return renumberYAxisAction; } + public ActionFactory.ExpandSelectionAction getExpandSelectionAllAction() { + if (expandSelectionAllAction == null) { + expandSelectionAllAction = ActionFactory.getInstance().createExpandSelectionAction( + plugInPort, ExpansionMode.ALL); + } + return expandSelectionAllAction; + } + + public ActionFactory.ExpandSelectionAction getExpandSelectionImmediateAction() { + if (expandSelectionImmediateAction == null) { + expandSelectionImmediateAction = ActionFactory.getInstance().createExpandSelectionAction( + plugInPort, ExpansionMode.IMMEDIATE); + } + return expandSelectionImmediateAction; + } + + public ActionFactory.ExpandSelectionAction getExpandSelectionSameTypeAction() { + if (expandSelectionSameTypeAction == null) { + expandSelectionSameTypeAction = ActionFactory.getInstance().createExpandSelectionAction( + plugInPort, ExpansionMode.SAME_TYPE); + } + return expandSelectionSameTypeAction; + } + @Override public void connect(IPlugInPort plugInPort) { this.plugInPort = plugInPort; @@ -173,6 +202,10 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { swingUI.injectSubmenu(RENUMBER_TITLE, IconLoader.Sort.getIcon(), EDIT_TITLE); swingUI.injectMenuAction(getRenumberXAxisAction(), RENUMBER_TITLE); swingUI.injectMenuAction(getRenumberYAxisAction(), RENUMBER_TITLE); + swingUI.injectSubmenu(EXPAND_TITLE, IconLoader.BranchAdd.getIcon(), EDIT_TITLE); + swingUI.injectMenuAction(getExpandSelectionAllAction(), EXPAND_TITLE); + swingUI.injectMenuAction(getExpandSelectionImmediateAction(), EXPAND_TITLE); + swingUI.injectMenuAction(getExpandSelectionSameTypeAction(), EXPAND_TITLE); swingUI.injectMenuAction(null, EDIT_TITLE); swingUI.injectMenuAction(actionFactory.createEditProjectAction(plugInPort), EDIT_TITLE); @@ -209,6 +242,9 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { getEditSelectionAction().setEnabled(enabled); getDeleteSelectionAction().setEnabled(enabled); getGroupAction().setEnabled(enabled); + getExpandSelectionAllAction().setEnabled(enabled); + getExpandSelectionImmediateAction().setEnabled(enabled); + getExpandSelectionSameTypeAction().setEnabled(enabled); getUngroupAction().setEnabled(enabled); getSendToBackAction().setEnabled(enabled); getBringToFrontAction().setEnabled(enabled); diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/plugins/statusbar/StatusBar.java b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/plugins/statusbar/StatusBar.java index a552e562..7c940112 100644 --- a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/plugins/statusbar/StatusBar.java +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/swing/plugins/statusbar/StatusBar.java @@ -261,10 +261,16 @@ public class StatusBar extends JPanel implements IPlugIn { statusText = "Drag control point(s) of " + formattedNames + ""; } else if (selectedComponentNames != null && !selectedComponentNames.isEmpty()) { StringBuilder builder = new StringBuilder(); - builder.append(Utils.toCommaString(selectedComponentNames)); + builder.append(Utils.toCommaString(selectedComponentNames.subList(0, 20))); + if (selectedComponentNames.size() > 20) { + builder.append(" and " + (selectedComponentNames.size() - 20) + " more"); + } if (!stuckComponentNames.isEmpty()) { builder.append(" (hold Ctrl and drag to unstuck from "); - builder.append(Utils.toCommaString(stuckComponentNames)); + builder.append(Utils.toCommaString(stuckComponentNames.subList(0, 5))); + if (stuckComponentNames.size() > 5) { + builder.append(" and " + (stuckComponentNames.size() - 5) + " more"); + } builder.append(")"); } statusText = "Selection: " + builder.toString() + ""; diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/update.xml b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/update.xml index e6d38750..8cab12b5 100644 --- a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/update.xml +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/update.xml @@ -453,5 +453,25 @@ http://code.google.com/p/diy-layout-creator/downloads/list + + + 3 + 3 + 0 + + 2012-02-25 20:00:00.000 CET + + + + NEW_FEATURE + Expand selection feature, useful for debugging + + + IMPROVEMENT + Limit length of text in the status bar using "and X more" suffix + + + http://code.google.com/p/diy-layout-creator/downloads/list + \ No newline at end of file