mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 17:22:09 +10:00
Added "Snap To Objects" feature that snaps control points to control
points of the nearest components
This commit is contained in:
@@ -60,7 +60,8 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
|
||||
public static final String EXPORT_GRID_KEY = "exportGrid";
|
||||
public static final String STICKY_POINTS_KEY = "stickyPoints";
|
||||
public static final String METRIC_KEY = "metric";
|
||||
public static final String SNAP_TO_GRID_KEY = "snapToGrid";
|
||||
|
||||
public static final String SNAP_TO_KEY = "snapTo";
|
||||
public static final String CONTINUOUS_CREATION_KEY = "continuousCreation";
|
||||
public static final String AUTO_EDIT_KEY = "autoEdit";
|
||||
public static final String ABNORMAL_EXIT_KEY = "abnormalExit";
|
||||
@@ -77,6 +78,11 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
|
||||
public static final String EXTRA_SPACE_KEY = "extraSpace";
|
||||
public static final String FAVORITES_KEY = "favorites";
|
||||
|
||||
public static final String SNAP_TO_NONE = "None";
|
||||
public static final String SNAP_TO_GRID = "Grid";
|
||||
public static final String SNAP_TO_OBJECTS = "Objects";
|
||||
public static final String SNAP_TO_DEFAULT = SNAP_TO_GRID;
|
||||
|
||||
public static final int DND_TOGGLE_STICKY = 0x1;
|
||||
public static final int DND_TOGGLE_SNAP = 0x40000000;
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.List;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.measures.Size;
|
||||
|
||||
public class CalcUtils {
|
||||
@@ -43,4 +45,16 @@ public class CalcUtils {
|
||||
int y = roundToGrid(point.y, gridSpacing);
|
||||
point.setLocation(x, y);
|
||||
}
|
||||
|
||||
public static void snapPointToObjects(Point point, Size gridSpacing, IDIYComponent<?> component, List<IDIYComponent<?>> components) {
|
||||
for (IDIYComponent<?> c : components) {
|
||||
if (c == component)
|
||||
continue;
|
||||
for (int i = 0; i < c.getControlPointCount(); i++)
|
||||
if (c.isControlPointSticky(i) && point.distance(c.getControlPoint(i)) < gridSpacing.convertToPixels() / 2) {
|
||||
point.setLocation(c.getControlPoint(i));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -740,10 +740,12 @@ public class Presenter implements IPlugInPort {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean snapToGrid = ConfigurationManager.getInstance().readBoolean(IPlugInPort.SNAP_TO_GRID_KEY, true);
|
||||
String snapTo = ConfigurationManager.getInstance().readString(IPlugInPort.SNAP_TO_KEY, IPlugInPort.SNAP_TO_DEFAULT);
|
||||
if (shiftDown) {
|
||||
snapToGrid = !snapToGrid;
|
||||
snapTo = IPlugInPort.SNAP_TO_NONE;
|
||||
}
|
||||
boolean snapToGrid = snapTo.equalsIgnoreCase(IPlugInPort.SNAP_TO_GRID);
|
||||
boolean snapToObjects = snapTo.equalsIgnoreCase(IPlugInPort.SNAP_TO_OBJECTS);
|
||||
|
||||
if (altDown) {
|
||||
Project oldProject = null;
|
||||
@@ -804,7 +806,7 @@ public class Presenter implements IPlugInPort {
|
||||
}
|
||||
|
||||
Project oldProject = currentProject.clone();
|
||||
moveComponents(controlPointMap, dx, dy, snapToGrid);
|
||||
moveComponents(controlPointMap, dx, dy, snapToGrid, snapToObjects);
|
||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Move Selection");
|
||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||
return true;
|
||||
@@ -1009,7 +1011,7 @@ public class Presenter implements IPlugInPort {
|
||||
int dy = (int) yOffset.convertToPixels();
|
||||
|
||||
Project oldProject = currentProject.clone();
|
||||
moveComponents(controlPointMap, dx, dy, false);
|
||||
moveComponents(controlPointMap, dx, dy, false, false);
|
||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Move Selection");
|
||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||
drawingManager.clearContinuityArea();
|
||||
@@ -1171,10 +1173,17 @@ public class Presenter implements IPlugInPort {
|
||||
}
|
||||
|
||||
private boolean isSnapToGrid() {
|
||||
boolean snapToGrid = ConfigurationManager.getInstance().readBoolean(IPlugInPort.SNAP_TO_GRID_KEY, true);
|
||||
String snapTo = ConfigurationManager.getInstance().readString(IPlugInPort.SNAP_TO_KEY, IPlugInPort.SNAP_TO_DEFAULT);
|
||||
if (this.dragAction == IPlugInPort.DND_TOGGLE_SNAP)
|
||||
snapToGrid = !snapToGrid;
|
||||
return snapToGrid;
|
||||
return false;
|
||||
return snapTo.equalsIgnoreCase(IPlugInPort.SNAP_TO_GRID);
|
||||
}
|
||||
|
||||
private boolean isSnapToObjects() {
|
||||
String snapTo = ConfigurationManager.getInstance().readString(IPlugInPort.SNAP_TO_KEY, IPlugInPort.SNAP_TO_DEFAULT);
|
||||
if (this.dragAction == IPlugInPort.DND_TOGGLE_SNAP)
|
||||
return false;
|
||||
return snapTo.equalsIgnoreCase(IPlugInPort.SNAP_TO_OBJECTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1188,7 +1197,7 @@ public class Presenter implements IPlugInPort {
|
||||
int dx = (scaledPoint.x - previousDragPoint.x);
|
||||
int dy = (scaledPoint.y - previousDragPoint.y);
|
||||
|
||||
Point actualD = moveComponents(this.controlPointMap, dx, dy, isSnapToGrid());
|
||||
Point actualD = moveComponents(this.controlPointMap, dx, dy, isSnapToGrid(), isSnapToObjects());
|
||||
if (actualD == null)
|
||||
return true;
|
||||
|
||||
@@ -1212,7 +1221,7 @@ public class Presenter implements IPlugInPort {
|
||||
return true;
|
||||
}
|
||||
|
||||
private Point moveComponents(Map<IDIYComponent<?>, Set<Integer>> controlPointMap, int dx, int dy, boolean snapToGrid) {
|
||||
private Point moveComponents(Map<IDIYComponent<?>, Set<Integer>> controlPointMap, int dx, int dy, boolean snapToGrid, boolean snapToObjects) {
|
||||
// After we make the transfer and snap to grid, calculate actual dx
|
||||
// and dy. We'll use them to translate the previous drag point.
|
||||
int actualDx = 0;
|
||||
@@ -1232,6 +1241,8 @@ public class Presenter implements IPlugInPort {
|
||||
testPoint.translate(dx, dy);
|
||||
if (snapToGrid) {
|
||||
CalcUtils.snapPointToGrid(testPoint, currentProject.getGridSpacing());
|
||||
} else if (snapToObjects) {
|
||||
CalcUtils.snapPointToObjects(testPoint, currentProject.getGridSpacing(), entry.getKey(), currentProject.getComponents());
|
||||
}
|
||||
|
||||
actualDx = testPoint.x - firstPoint.x;
|
||||
|
||||
@@ -2714,6 +2714,10 @@
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>New app bundle for Mac OS using appbundler instead of javabundler</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added "Snap To Objects" feature that snaps control points to control points of the nearest components</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>New Mac OS app icon</description>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -242,6 +242,10 @@ public class ActionFactory {
|
||||
return new ConfigAction(plugInPort, title, configKey, defaultValue, tipKey);
|
||||
}
|
||||
|
||||
public ToggleAction createToggleAction(String title, String configKey, String groupName, String defaultValue) {
|
||||
return new ToggleAction(title, configKey, groupName, defaultValue);
|
||||
}
|
||||
|
||||
public ThemeAction createThemeAction(IPlugInPort plugInPort, Theme theme) {
|
||||
return new ThemeAction(plugInPort, theme);
|
||||
}
|
||||
@@ -1576,6 +1580,27 @@ public class ActionFactory {
|
||||
}
|
||||
}
|
||||
|
||||
public static class ToggleAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String configKey;
|
||||
|
||||
public ToggleAction(String title, String configKey, String groupName, String defaultValue) {
|
||||
super();
|
||||
this.configKey = configKey;
|
||||
putValue(AbstractAction.NAME, title);
|
||||
putValue(IView.RADIO_BUTTON_GROUP_KEY, groupName);
|
||||
putValue(AbstractAction.SELECTED_KEY, ConfigurationManager.getInstance().readString(configKey, defaultValue).equalsIgnoreCase(title));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info(getValue(AbstractAction.NAME) + " toggle triggered");
|
||||
ConfigurationManager.getInstance().writeValue(configKey, getValue(AbstractAction.NAME));
|
||||
}
|
||||
}
|
||||
|
||||
public static class ThemeAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -46,6 +46,7 @@ public class ConfigPlugin implements IPlugIn {
|
||||
|
||||
private static final String CONFIG_MENU = "Config";
|
||||
private static final String THEME_MENU = "Theme";
|
||||
private static final String SNAP_MENU = "Snap To...";
|
||||
private static final String COMPONENT_BROWSER_MENU = "Toolbox";
|
||||
public static final String COMPONENT_BROWSER = "componentBrowser";
|
||||
public static final String SEARCHABLE_TREE = "Searchable Tree";
|
||||
@@ -96,12 +97,19 @@ public class ConfigPlugin implements IPlugIn {
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Rulers", IPlugInPort.SHOW_RULERS_KEY, true),
|
||||
CONFIG_MENU);
|
||||
swingUI.injectSubmenu(SNAP_MENU, null, CONFIG_MENU);
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Grid", IPlugInPort.SHOW_GRID_KEY, true),
|
||||
CONFIG_MENU);
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Snap to Grid", IPlugInPort.SNAP_TO_GRID_KEY, true),
|
||||
CONFIG_MENU);
|
||||
ActionFactory.getInstance().createToggleAction("None", IPlugInPort.SNAP_TO_KEY, SNAP_MENU, IPlugInPort.SNAP_TO_DEFAULT),
|
||||
SNAP_MENU);
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createToggleAction("Grid", IPlugInPort.SNAP_TO_KEY, SNAP_MENU, IPlugInPort.SNAP_TO_DEFAULT),
|
||||
SNAP_MENU);
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance().createToggleAction("Objects", IPlugInPort.SNAP_TO_KEY, SNAP_MENU, IPlugInPort.SNAP_TO_DEFAULT),
|
||||
SNAP_MENU);
|
||||
swingUI.injectMenuAction(
|
||||
ActionFactory.getInstance()
|
||||
.createConfigAction(plugInPort, "Sticky Points", IPlugInPort.STICKY_POINTS_KEY, true), CONFIG_MENU);
|
||||
|
||||
Reference in New Issue
Block a user