mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 09:12: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 EXPORT_GRID_KEY = "exportGrid";
|
||||||
public static final String STICKY_POINTS_KEY = "stickyPoints";
|
public static final String STICKY_POINTS_KEY = "stickyPoints";
|
||||||
public static final String METRIC_KEY = "metric";
|
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 CONTINUOUS_CREATION_KEY = "continuousCreation";
|
||||||
public static final String AUTO_EDIT_KEY = "autoEdit";
|
public static final String AUTO_EDIT_KEY = "autoEdit";
|
||||||
public static final String ABNORMAL_EXIT_KEY = "abnormalExit";
|
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 EXTRA_SPACE_KEY = "extraSpace";
|
||||||
public static final String FAVORITES_KEY = "favorites";
|
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_STICKY = 0x1;
|
||||||
public static final int DND_TOGGLE_SNAP = 0x40000000;
|
public static final int DND_TOGGLE_SNAP = 0x40000000;
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,9 @@
|
|||||||
package org.diylc.presenter;
|
package org.diylc.presenter;
|
||||||
|
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.diylc.core.IDIYComponent;
|
||||||
import org.diylc.core.measures.Size;
|
import org.diylc.core.measures.Size;
|
||||||
|
|
||||||
public class CalcUtils {
|
public class CalcUtils {
|
||||||
@@ -43,4 +45,16 @@ public class CalcUtils {
|
|||||||
int y = roundToGrid(point.y, gridSpacing);
|
int y = roundToGrid(point.y, gridSpacing);
|
||||||
point.setLocation(x, y);
|
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;
|
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) {
|
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) {
|
if (altDown) {
|
||||||
Project oldProject = null;
|
Project oldProject = null;
|
||||||
@@ -804,7 +806,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Project oldProject = currentProject.clone();
|
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.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Move Selection");
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
return true;
|
return true;
|
||||||
@@ -1009,7 +1011,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
int dy = (int) yOffset.convertToPixels();
|
int dy = (int) yOffset.convertToPixels();
|
||||||
|
|
||||||
Project oldProject = currentProject.clone();
|
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.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Move Selection");
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
drawingManager.clearContinuityArea();
|
drawingManager.clearContinuityArea();
|
||||||
@@ -1171,10 +1173,17 @@ public class Presenter implements IPlugInPort {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSnapToGrid() {
|
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)
|
if (this.dragAction == IPlugInPort.DND_TOGGLE_SNAP)
|
||||||
snapToGrid = !snapToGrid;
|
return false;
|
||||||
return snapToGrid;
|
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
|
@Override
|
||||||
@@ -1188,7 +1197,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
int dx = (scaledPoint.x - previousDragPoint.x);
|
int dx = (scaledPoint.x - previousDragPoint.x);
|
||||||
int dy = (scaledPoint.y - previousDragPoint.y);
|
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)
|
if (actualD == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -1212,7 +1221,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
return true;
|
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
|
// After we make the transfer and snap to grid, calculate actual dx
|
||||||
// and dy. We'll use them to translate the previous drag point.
|
// and dy. We'll use them to translate the previous drag point.
|
||||||
int actualDx = 0;
|
int actualDx = 0;
|
||||||
@@ -1232,6 +1241,8 @@ public class Presenter implements IPlugInPort {
|
|||||||
testPoint.translate(dx, dy);
|
testPoint.translate(dx, dy);
|
||||||
if (snapToGrid) {
|
if (snapToGrid) {
|
||||||
CalcUtils.snapPointToGrid(testPoint, currentProject.getGridSpacing());
|
CalcUtils.snapPointToGrid(testPoint, currentProject.getGridSpacing());
|
||||||
|
} else if (snapToObjects) {
|
||||||
|
CalcUtils.snapPointToObjects(testPoint, currentProject.getGridSpacing(), entry.getKey(), currentProject.getComponents());
|
||||||
}
|
}
|
||||||
|
|
||||||
actualDx = testPoint.x - firstPoint.x;
|
actualDx = testPoint.x - firstPoint.x;
|
||||||
|
|||||||
@@ -2714,6 +2714,10 @@
|
|||||||
<changeType>NEW_FEATURE</changeType>
|
<changeType>NEW_FEATURE</changeType>
|
||||||
<description>New app bundle for Mac OS using appbundler instead of javabundler</description>
|
<description>New app bundle for Mac OS using appbundler instead of javabundler</description>
|
||||||
</org.diylc.appframework.update.Change>
|
</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>
|
<org.diylc.appframework.update.Change>
|
||||||
<changeType>NEW_FEATURE</changeType>
|
<changeType>NEW_FEATURE</changeType>
|
||||||
<description>New Mac OS app icon</description>
|
<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);
|
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) {
|
public ThemeAction createThemeAction(IPlugInPort plugInPort, Theme theme) {
|
||||||
return new ThemeAction(plugInPort, 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 {
|
public static class ThemeAction extends AbstractAction {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
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 CONFIG_MENU = "Config";
|
||||||
private static final String THEME_MENU = "Theme";
|
private static final String THEME_MENU = "Theme";
|
||||||
|
private static final String SNAP_MENU = "Snap To...";
|
||||||
private static final String COMPONENT_BROWSER_MENU = "Toolbox";
|
private static final String COMPONENT_BROWSER_MENU = "Toolbox";
|
||||||
public static final String COMPONENT_BROWSER = "componentBrowser";
|
public static final String COMPONENT_BROWSER = "componentBrowser";
|
||||||
public static final String SEARCHABLE_TREE = "Searchable Tree";
|
public static final String SEARCHABLE_TREE = "Searchable Tree";
|
||||||
@@ -96,12 +97,19 @@ public class ConfigPlugin implements IPlugIn {
|
|||||||
swingUI.injectMenuAction(
|
swingUI.injectMenuAction(
|
||||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Rulers", IPlugInPort.SHOW_RULERS_KEY, true),
|
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Rulers", IPlugInPort.SHOW_RULERS_KEY, true),
|
||||||
CONFIG_MENU);
|
CONFIG_MENU);
|
||||||
|
swingUI.injectSubmenu(SNAP_MENU, null, CONFIG_MENU);
|
||||||
swingUI.injectMenuAction(
|
swingUI.injectMenuAction(
|
||||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Grid", IPlugInPort.SHOW_GRID_KEY, true),
|
ActionFactory.getInstance().createConfigAction(plugInPort, "Show Grid", IPlugInPort.SHOW_GRID_KEY, true),
|
||||||
CONFIG_MENU);
|
CONFIG_MENU);
|
||||||
swingUI.injectMenuAction(
|
swingUI.injectMenuAction(
|
||||||
ActionFactory.getInstance().createConfigAction(plugInPort, "Snap to Grid", IPlugInPort.SNAP_TO_GRID_KEY, true),
|
ActionFactory.getInstance().createToggleAction("None", IPlugInPort.SNAP_TO_KEY, SNAP_MENU, IPlugInPort.SNAP_TO_DEFAULT),
|
||||||
CONFIG_MENU);
|
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(
|
swingUI.injectMenuAction(
|
||||||
ActionFactory.getInstance()
|
ActionFactory.getInstance()
|
||||||
.createConfigAction(plugInPort, "Sticky Points", IPlugInPort.STICKY_POINTS_KEY, true), CONFIG_MENU);
|
.createConfigAction(plugInPort, "Sticky Points", IPlugInPort.STICKY_POINTS_KEY, true), CONFIG_MENU);
|
||||||
|
|||||||
Reference in New Issue
Block a user