Select components from context menu even when they are under other components

This commit is contained in:
bancika
2012-02-12 14:36:18 +00:00
parent 616b09b4b2
commit ebf06841a0
12 changed files with 181 additions and 100 deletions
@@ -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);
}
@@ -4,7 +4,6 @@ import java.awt.Cursor;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Point; import java.awt.Point;
import java.awt.dnd.DnDConstants;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -29,7 +28,7 @@ import org.diylc.core.Theme;
* @see IMessageListener * @see IMessageListener
* @see EventType * @see EventType
*/ */
public interface IPlugInPort { public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor {
public static final String ANTI_ALIASING_KEY = "antiAliasing"; public static final String ANTI_ALIASING_KEY = "antiAliasing";
public static final String HI_QUALITY_RENDER_KEY = "hiQualityRender"; public static final String HI_QUALITY_RENDER_KEY = "hiQualityRender";
@@ -163,89 +162,6 @@ public interface IPlugInPort {
*/ */
void setZoomLevel(double zoomLevel); 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<IDIYComponent<?>> 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<IDIYComponent<?>> 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. * Returns current version number.
* *
@@ -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<IDIYComponent<?>> 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<IDIYComponent<?>> newSelection);
/**
* Finds all components at the specified location, sorted by z-index from
* top to bottom.
*
* @param point
* @return
*/
List<IDIYComponent<?>> findComponentsAt(Point point);
/**
* Selects all components in the project.
*/
void selectAll();
}
@@ -31,7 +31,7 @@ public enum IconLoader {
"donate.png"), Bug("bug.png"), IconLarge("icon_large.png"), IconMedium( "donate.png"), Bug("bug.png"), IconLarge("icon_large.png"), IconMedium(
"icon_medium.png"), IconSmall("icon_small.png"), DocumentEdit("document_edit.png"), EditComponent( "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( "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; protected String name;
Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

@@ -362,7 +362,7 @@ public class DrawingManager {
for (int i = 0; i < project.getComponents().size(); i++) { for (int i = 0; i < project.getComponents().size(); i++) {
Area area = componentAreaMap.get(project.getComponents().get(i)); Area area = componentAreaMap.get(project.getComponents().get(i));
if (area != null && area.contains(point)) { if (area != null && area.contains(point)) {
components.add(project.getComponents().get(i)); components.add(0, project.getComponents().get(i));
} }
} }
return components; return components;
@@ -341,7 +341,7 @@ public class Presenter implements IPlugInPort {
* *
* @return * @return
*/ */
private List<IDIYComponent<?>> findComponentsAt(Point point) { public List<IDIYComponent<?>> findComponentsAtScaled(Point point) {
List<IDIYComponent<?>> components = drawingManager.findComponentsAt(point, currentProject); List<IDIYComponent<?>> components = drawingManager.findComponentsAt(point, currentProject);
Iterator<IDIYComponent<?>> iterator = components.iterator(); Iterator<IDIYComponent<?>> iterator = components.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
@@ -352,6 +352,13 @@ public class Presenter implements IPlugInPort {
return components; return components;
} }
@Override
public List<IDIYComponent<?>> findComponentsAt(Point point) {
Point scaledPoint = scalePoint(point);
List<IDIYComponent<?>> components = findComponentsAtScaled(scaledPoint);
return components;
}
@Override @Override
public void mouseClicked(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown, public void mouseClicked(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown,
int clickCount) { int clickCount) {
@@ -455,14 +462,14 @@ public class Presenter implements IPlugInPort {
} else { } else {
List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>( List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>(
selectedComponents); selectedComponents);
List<IDIYComponent<?>> components = findComponentsAt(scaledPoint); List<IDIYComponent<?>> components = findComponentsAtScaled(scaledPoint);
// If there's nothing under mouse cursor deselect all. // If there's nothing under mouse cursor deselect all.
if (components.isEmpty()) { if (components.isEmpty()) {
if (!ctrlDown) { if (!ctrlDown) {
newSelection.clear(); newSelection.clear();
} }
} else { } else {
IDIYComponent<?> component = components.get(components.size() - 1); IDIYComponent<?> component = components.get(0);
// If ctrl is pressed just toggle the component under mouse // If ctrl is pressed just toggle the component under mouse
// cursor. // cursor.
if (ctrlDown) { if (ctrlDown) {
@@ -584,7 +591,8 @@ public class Presenter implements IPlugInPort {
@Override @Override
public void selectAll() { public void selectAll() {
LOG.info("selectAll()"); LOG.info("selectAll()");
List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>(currentProject.getComponents()); List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>(currentProject
.getComponents());
newSelection.removeAll(getLockedComponents()); newSelection.removeAll(getLockedComponents());
updateSelection(newSelection); updateSelection(newSelection);
// messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED, // messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED,
@@ -604,7 +612,9 @@ public class Presenter implements IPlugInPort {
LOG.debug(String.format("dragStarted(%s, %s)", point, dragAction)); LOG.debug(String.format("dragStarted(%s, %s)", point, dragAction));
if (instantiationManager.getComponentTypeSlot() != null) { if (instantiationManager.getComponentTypeSlot() != null) {
LOG.debug("Cannot start drag because a new component is being created."); 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; return;
} }
this.dragInProgress = true; this.dragInProgress = true;
@@ -612,7 +622,7 @@ public class Presenter implements IPlugInPort {
preDragProject = cloner.deepClone(currentProject); preDragProject = cloner.deepClone(currentProject);
Point scaledPoint = scalePoint(point); Point scaledPoint = scalePoint(point);
this.previousDragPoint = scaledPoint; this.previousDragPoint = scaledPoint;
List<IDIYComponent<?>> components = findComponentsAt(scaledPoint); List<IDIYComponent<?>> components = findComponentsAtScaled(scaledPoint);
if (!this.controlPointMap.isEmpty()) { if (!this.controlPointMap.isEmpty()) {
// If we're dragging control points reset selection. // If we're dragging control points reset selection.
updateSelection(new ArrayList<IDIYComponent<?>>(this.controlPointMap.keySet())); updateSelection(new ArrayList<IDIYComponent<?>>(this.controlPointMap.keySet()));
@@ -631,7 +641,7 @@ public class Presenter implements IPlugInPort {
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
} else { } else {
// Take the last component, i.e. the top order component. // 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 // If the component under the cursor is not already selected, make
// it into the only selected component. // it into the only selected component.
if (!selectedComponents.contains(component)) { if (!selectedComponents.contains(component)) {
@@ -31,7 +31,7 @@ public enum IconLoader {
"donate.png"), Bug("bug.png"), IconLarge("icon_large.png"), IconMedium( "donate.png"), Bug("bug.png"), IconLarge("icon_large.png"), IconMedium(
"icon_medium.png"), IconSmall("icon_small.png"), DocumentEdit("document_edit.png"), EditComponent( "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( "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; protected String name;
Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

@@ -1,17 +1,24 @@
package org.diylc.swing.plugins.canvas; package org.diylc.swing.plugins.canvas;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner; import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.Transferable; import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener; import java.awt.event.MouseWheelListener;
import java.util.ArrayList;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
@@ -22,8 +29,10 @@ import org.diylc.common.BadPositionException;
import org.diylc.common.EventType; import org.diylc.common.EventType;
import org.diylc.common.IPlugIn; import org.diylc.common.IPlugIn;
import org.diylc.common.IPlugInPort; import org.diylc.common.IPlugInPort;
import org.diylc.core.IDIYComponent;
import org.diylc.core.measures.Size; import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.SizeUnit;
import org.diylc.images.IconLoader;
import org.diylc.presenter.Presenter; import org.diylc.presenter.Presenter;
import org.diylc.swing.ActionFactory; import org.diylc.swing.ActionFactory;
import org.diylc.swing.ISwingUI; import org.diylc.swing.ISwingUI;
@@ -39,6 +48,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
private RulerScrollPane scrollPane; private RulerScrollPane scrollPane;
private CanvasPanel canvasPanel; private CanvasPanel canvasPanel;
private JPopupMenu popupMenu; private JPopupMenu popupMenu;
private JMenu selectionMenu;
private ActionFactory.CutAction cutAction; private ActionFactory.CutAction cutAction;
private ActionFactory.CopyAction copyAction; private ActionFactory.CopyAction copyAction;
@@ -99,7 +109,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
getSendToBackAction().setEnabled(enabled); getSendToBackAction().setEnabled(enabled);
getBringToFrontAction().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; return scrollPane;
} }
private void showPopupAt(int x, int y) {
updateSelectionMenu(x, y);
getPopupMenu().show(canvasPanel, x, y);
}
public JPopupMenu getPopupMenu() { public JPopupMenu getPopupMenu() {
if (popupMenu == null) { if (popupMenu == null) {
popupMenu = new JPopupMenu(); popupMenu = new JPopupMenu();
popupMenu.add(getSelectionMenu());
popupMenu.addSeparator();
popupMenu.add(getCutAction()); popupMenu.add(getCutAction());
popupMenu.add(getCopyAction()); popupMenu.add(getCopyAction());
popupMenu.add(getPasteAction()); popupMenu.add(getPasteAction());
@@ -182,6 +199,33 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
return popupMenu; 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<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>();
newSelection.add(finalComponent);
plugInPort.updateSelection(newSelection);
plugInPort.refresh();
}
});
getSelectionMenu().add(item);
}
}
public ActionFactory.CutAction getCutAction() { public ActionFactory.CutAction getCutAction() {
if (cutAction == null) { if (cutAction == null) {
cutAction = ActionFactory.getInstance().createCutAction(plugInPort, clipboard, this); cutAction = ActionFactory.getInstance().createCutAction(plugInPort, clipboard, this);
@@ -418,6 +418,10 @@
<releaseDate>2012-02-01 20:00:00.000 CET</releaseDate> <releaseDate>2012-02-01 20:00:00.000 CET</releaseDate>
<name></name> <name></name>
<changes> <changes>
<com.diyfever.gui.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Select components from context menu even when they are under other components</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change> <com.diyfever.gui.update.Change>
<changeType>NEW_FEATURE</changeType> <changeType>NEW_FEATURE</changeType>
<description>Ctrl+Shift toggles "Snap to Grid" option</description> <description>Ctrl+Shift toggles "Snap to Grid" option</description>