diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/common/IMouseProcessor.java b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/common/IMouseProcessor.java new file mode 100644 index 00000000..33d837c6 --- /dev/null +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/common/IMouseProcessor.java @@ -0,0 +1,68 @@ +package org.diylc.common; + +import java.awt.Point; + +public interface IMouseProcessor { + + /** + * Notifies the presenter that mouse is clicked. + * + * Note: point coordinates are display based, i.e. scaled for zoom factor. + * + * @param point + * @param ctrlDown + * @param shiftDown + * @param altDown + * @param clickCount + */ + void mouseClicked(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown, + int clickCount); + + /** + * Notifies the presenter that mouse is moved. + * + * Note: point coordinates are display based, i.e. scaled for zoom factor. + * + * @param point + * @param ctrlDown + * @param shiftDown + * @param altDown + */ + void mouseMoved(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown); + + /** + * Notification that drag has been started from the specified point. + * + * Note: point coordinates are scaled for zoom factor. + * + * @param point + * @param dragAction + */ + void dragStarted(Point point, int dragAction); + + /** + * Checks if it's possible to drop over the specified point. + * + * Note: point coordinates are scaled for zoom factor. + * + * @param point + * @return + */ + boolean dragOver(Point point); + + /** + * Changes the current drag action during the dragging. + * + * @param dragAction + */ + void dragActionChanged(int dragAction); + + /** + * Notification that drag has been ended in the specified point. + * + * Note: point coordinates are scaled for zoom factor. + * + * @param point + */ + void dragEnded(Point point); +} diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/common/IPlugInPort.java b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/common/IPlugInPort.java index c1a75cd3..ca1fafc7 100644 --- a/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/common/IPlugInPort.java +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/common/IPlugInPort.java @@ -4,7 +4,6 @@ import java.awt.Cursor; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; -import java.awt.dnd.DnDConstants; import java.awt.geom.Point2D; import java.util.List; import java.util.Map; @@ -29,7 +28,7 @@ import org.diylc.core.Theme; * @see IMessageListener * @see EventType */ -public interface IPlugInPort { +public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor { public static final String ANTI_ALIASING_KEY = "antiAliasing"; public static final String HI_QUALITY_RENDER_KEY = "hiQualityRender"; @@ -45,7 +44,7 @@ public interface IPlugInPort { public static final String OUTLINE_KEY = "outline"; public static final String THEME_KEY = "theme"; public static final String RECENT_COMPONENTS_KEY = "recentComponents"; - + public static final int DND_TOGGLE_STICKY = 0x1; public static final int DND_TOGGLE_SNAP = 0x40000000; @@ -163,89 +162,6 @@ public interface IPlugInPort { */ void setZoomLevel(double zoomLevel); - /** - * Notifies the presenter that mouse is clicked. - * - * Note: point coordinates are display based, i.e. scaled for zoom factor. - * - * @param point - * @param ctrlDown - * @param shiftDown - * @param altDown - * @param clickCount - */ - void mouseClicked(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown, - int clickCount); - - /** - * Notifies the presenter that mouse is moved. - * - * Note: point coordinates are display based, i.e. scaled for zoom factor. - * - * @param point - * @param ctrlDown - * @param shiftDown - * @param altDown - */ - void mouseMoved(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown); - - /** - * Returns the current {@link ComponentTransferable}. - * - * @return - */ - List> getSelectedComponents(); - - /** - * Updates the selection with the specified list of component. Also, updates - * control point map with all components that are stuck to the newly - * selected components. - * - * @param newSelection - */ - void updateSelection(List> newSelection); - - /** - * Selects all components in the project. - */ - void selectAll(); - - /** - * Notification that drag has been started from the specified point. - * - * Note: point coordinates are scaled for zoom factor. - * - * @param point - * @param dragAction - */ - void dragStarted(Point point, int dragAction); - - /** - * Checks if it's possible to drop over the specified point. - * - * Note: point coordinates are scaled for zoom factor. - * - * @param point - * @return - */ - boolean dragOver(Point point); - - /** - * Changes the current drag action during the dragging. - * - * @param dragAction - */ - void dragActionChanged(int dragAction); - - /** - * Notification that drag has been ended in the specified point. - * - * Note: point coordinates are scaled for zoom factor. - * - * @param point - */ - void dragEnded(Point point); - /** * Returns current version number. * 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 new file mode 100644 index 00000000..ae5c834a --- /dev/null +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/common/ISelectionProcessor.java @@ -0,0 +1,39 @@ +package org.diylc.common; + +import java.awt.Point; +import java.util.List; + +import org.diylc.core.IDIYComponent; + +public interface ISelectionProcessor { + + /** + * Returns the current {@link ComponentTransferable}. + * + * @return + */ + List> getSelectedComponents(); + + /** + * Updates the selection with the specified list of component. Also, updates + * control point map with all components that are stuck to the newly + * selected components. + * + * @param newSelection + */ + void updateSelection(List> newSelection); + + /** + * Finds all components at the specified location, sorted by z-index from + * top to bottom. + * + * @param point + * @return + */ + List> findComponentsAt(Point point); + + /** + * Selects all components in the project. + */ + void selectAll(); +} diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/images/IconLoader.java b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/images/IconLoader.java index baef6933..75f1cede 100644 --- a/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/images/IconLoader.java +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/images/IconLoader.java @@ -31,7 +31,7 @@ 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"); + "pens.png"), Sort("sort.png"), ElementsSelection("elements_selection.png"); protected String name; diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/images/elements_selection.png b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/images/elements_selection.png new file mode 100644 index 00000000..be9d2df1 Binary files /dev/null and b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/images/elements_selection.png differ diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/presenter/DrawingManager.java b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/presenter/DrawingManager.java index 1b636a7a..048cc270 100644 --- a/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/presenter/DrawingManager.java +++ b/ diy-layout-creator --username bancika@gmail.com/diylc-core/src/org/diylc/presenter/DrawingManager.java @@ -362,7 +362,7 @@ public class DrawingManager { for (int i = 0; i < project.getComponents().size(); i++) { Area area = componentAreaMap.get(project.getComponents().get(i)); if (area != null && area.contains(point)) { - components.add(project.getComponents().get(i)); + components.add(0, project.getComponents().get(i)); } } return components; 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 c35599a1..97916d44 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 @@ -341,7 +341,7 @@ public class Presenter implements IPlugInPort { * * @return */ - private List> findComponentsAt(Point point) { + public List> findComponentsAtScaled(Point point) { List> components = drawingManager.findComponentsAt(point, currentProject); Iterator> iterator = components.iterator(); while (iterator.hasNext()) { @@ -352,6 +352,13 @@ public class Presenter implements IPlugInPort { return components; } + @Override + public List> findComponentsAt(Point point) { + Point scaledPoint = scalePoint(point); + List> components = findComponentsAtScaled(scaledPoint); + return components; + } + @Override public void mouseClicked(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown, int clickCount) { @@ -455,14 +462,14 @@ public class Presenter implements IPlugInPort { } else { List> newSelection = new ArrayList>( selectedComponents); - List> components = findComponentsAt(scaledPoint); + List> components = findComponentsAtScaled(scaledPoint); // If there's nothing under mouse cursor deselect all. if (components.isEmpty()) { if (!ctrlDown) { newSelection.clear(); } } else { - IDIYComponent component = components.get(components.size() - 1); + IDIYComponent component = components.get(0); // If ctrl is pressed just toggle the component under mouse // cursor. if (ctrlDown) { @@ -584,7 +591,8 @@ public class Presenter implements IPlugInPort { @Override public void selectAll() { LOG.info("selectAll()"); - List> newSelection = new ArrayList>(currentProject.getComponents()); + List> newSelection = new ArrayList>(currentProject + .getComponents()); newSelection.removeAll(getLockedComponents()); updateSelection(newSelection); // messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED, @@ -604,7 +612,9 @@ public class Presenter implements IPlugInPort { LOG.debug(String.format("dragStarted(%s, %s)", point, dragAction)); if (instantiationManager.getComponentTypeSlot() != null) { LOG.debug("Cannot start drag because a new component is being created."); - mouseClicked(point, dragAction == DnDConstants.ACTION_COPY, dragAction == DnDConstants.ACTION_LINK, dragAction == DnDConstants.ACTION_MOVE, 1); + mouseClicked(point, dragAction == DnDConstants.ACTION_COPY, + dragAction == DnDConstants.ACTION_LINK, dragAction == DnDConstants.ACTION_MOVE, + 1); return; } this.dragInProgress = true; @@ -612,7 +622,7 @@ public class Presenter implements IPlugInPort { preDragProject = cloner.deepClone(currentProject); Point scaledPoint = scalePoint(point); this.previousDragPoint = scaledPoint; - List> components = findComponentsAt(scaledPoint); + List> components = findComponentsAtScaled(scaledPoint); if (!this.controlPointMap.isEmpty()) { // If we're dragging control points reset selection. updateSelection(new ArrayList>(this.controlPointMap.keySet())); @@ -631,7 +641,7 @@ public class Presenter implements IPlugInPort { messageDispatcher.dispatchMessage(EventType.REPAINT); } else { // Take the last component, i.e. the top order component. - IDIYComponent component = components.get(components.size() - 1); + IDIYComponent component = components.get(0); // If the component under the cursor is not already selected, make // it into the only selected component. if (!selectedComponents.contains(component)) { @@ -665,7 +675,7 @@ public class Presenter implements IPlugInPort { } } } - + @Override public void dragActionChanged(int dragAction) { LOG.debug("dragActionChanged(" + dragAction + ")"); @@ -746,7 +756,7 @@ public class Presenter implements IPlugInPort { LOG.trace("Component count didn't change, done with expanding."); } } - + private boolean isSnapToGrid() { boolean snapToGrid = ConfigurationManager.getInstance().readBoolean( IPlugInPort.SNAP_TO_GRID_KEY, true); 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 b037c329..666c6181 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 baef6933..75f1cede 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,7 @@ 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"); + "pens.png"), Sort("sort.png"), ElementsSelection("elements_selection.png"); protected String name; diff --git a/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/images/elements_selection.png b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/images/elements_selection.png new file mode 100644 index 00000000..be9d2df1 Binary files /dev/null and b/ diy-layout-creator --username bancika@gmail.com/diylc-swing/src/org/diylc/images/elements_selection.png differ 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 2fc8ffb9..d75bb0db 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 @@ -1,17 +1,24 @@ package org.diylc.swing.plugins.canvas; import java.awt.Dimension; +import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.ClipboardOwner; import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; +import java.util.ArrayList; import java.util.EnumSet; +import java.util.List; +import javax.swing.JMenu; +import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.SwingConstants; @@ -22,8 +29,10 @@ import org.diylc.common.BadPositionException; import org.diylc.common.EventType; import org.diylc.common.IPlugIn; import org.diylc.common.IPlugInPort; +import org.diylc.core.IDIYComponent; import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; +import org.diylc.images.IconLoader; import org.diylc.presenter.Presenter; import org.diylc.swing.ActionFactory; import org.diylc.swing.ISwingUI; @@ -39,6 +48,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { private RulerScrollPane scrollPane; private CanvasPanel canvasPanel; private JPopupMenu popupMenu; + private JMenu selectionMenu; private ActionFactory.CutAction cutAction; private ActionFactory.CopyAction copyAction; @@ -99,7 +109,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { getSendToBackAction().setEnabled(enabled); getBringToFrontAction().setEnabled(enabled); - getPopupMenu().show(canvasPanel, e.getX(), e.getY()); + showPopupAt(e.getX(), e.getY()); } } }); @@ -163,9 +173,16 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { return scrollPane; } + private void showPopupAt(int x, int y) { + updateSelectionMenu(x, y); + getPopupMenu().show(canvasPanel, x, y); + } + public JPopupMenu getPopupMenu() { if (popupMenu == null) { popupMenu = new JPopupMenu(); + popupMenu.add(getSelectionMenu()); + popupMenu.addSeparator(); popupMenu.add(getCutAction()); popupMenu.add(getCopyAction()); popupMenu.add(getPasteAction()); @@ -182,6 +199,33 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { return popupMenu; } + public JMenu getSelectionMenu() { + if (selectionMenu == null) { + selectionMenu = new JMenu("Select"); + selectionMenu.setIcon(IconLoader.ElementsSelection.getIcon()); + } + return selectionMenu; + } + + private void updateSelectionMenu(int x, int y) { + getSelectionMenu().removeAll(); + for (IDIYComponent component : plugInPort.findComponentsAt(new Point(x, y))) { + JMenuItem item = new JMenuItem(component.getName()); + final IDIYComponent finalComponent = component; + item.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + List> newSelection = new ArrayList>(); + newSelection.add(finalComponent); + plugInPort.updateSelection(newSelection); + plugInPort.refresh(); + } + }); + getSelectionMenu().add(item); + } + } + public ActionFactory.CutAction getCutAction() { if (cutAction == null) { cutAction = ActionFactory.getInstance().createCutAction(plugInPort, clipboard, this); 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 d0fea704..83e49f13 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 @@ -417,7 +417,11 @@ 2012-02-01 20:00:00.000 CET - + + + NEW_FEATURE + Select components from context menu even when they are under other components + NEW_FEATURE Ctrl+Shift toggles "Snap to Grid" option