mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-07 12:24:58 +10:00
double click to instant creation
This commit is contained in:
@@ -667,11 +667,16 @@ public class Presenter implements IPlugInPort {
|
||||
private void addPendingComponentsToProject(Point2D scaledPoint, ComponentType componentTypeSlot, Template template, String[] model,
|
||||
Project oldProject) {
|
||||
List<IDIYComponent<?>> componentSlot = instantiationManager.getComponentSlot();
|
||||
Point2D firstPoint = componentSlot.get(0).getControlPoint(0);
|
||||
// don't allow to create component with the same points
|
||||
if (scaledPoint == null || scaledPoint.equals(firstPoint))
|
||||
if (scaledPoint == null) {
|
||||
return;
|
||||
// componentSlot.get(0).setControlPoint(scaledPoint, 1);
|
||||
}
|
||||
// A slot with no first control point was instantiated up front and already carries its default
|
||||
// shape, so it legitimately lands with the first control point under the cursor. Only reject a
|
||||
// degenerate component when the user is placing it point by point.
|
||||
boolean instantiatedUpFront = instantiationManager.getFirstControlPoint() == null;
|
||||
if (!instantiatedUpFront && scaledPoint.equals(componentSlot.get(0).getControlPoint(0))) {
|
||||
return;
|
||||
}
|
||||
List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>();
|
||||
for (IDIYComponent<?> component : componentSlot) {
|
||||
addComponent(component, true);
|
||||
@@ -691,7 +696,7 @@ public class Presenter implements IPlugInPort {
|
||||
editSelection();
|
||||
}
|
||||
if (configManager.readBoolean(IPlugInPort.CONTINUOUS_CREATION_KEY, false)) {
|
||||
setNewComponentTypeSlot(componentTypeSlot, template, model, false);
|
||||
setNewComponentTypeSlot(componentTypeSlot, template, model, instantiatedUpFront);
|
||||
} else {
|
||||
setNewComponentTypeSlot(null, null, null, false);
|
||||
}
|
||||
@@ -844,16 +849,17 @@ public class Presenter implements IPlugInPort {
|
||||
} else if (isSnapToObjects()) {
|
||||
CalcUtils.snapPointToObjects(previousScaledPoint, currentProject.getGridSpacing(), null, currentProject.getComponents());
|
||||
}
|
||||
boolean refresh = false;
|
||||
switch (instantiationManager.getComponentTypeSlot().getCreationMethod()) {
|
||||
case POINT_BY_POINT:
|
||||
refresh = instantiationManager.updatePointByPoint(previousScaledPoint);
|
||||
break;
|
||||
case SINGLE_CLICK:
|
||||
refresh =
|
||||
instantiationManager.updateSingleClick(previousScaledPoint, isSnapToGrid(),
|
||||
currentProject.getGridSpacing());
|
||||
break;
|
||||
// What the cursor does is decided by how the slot was armed rather than by the creation
|
||||
// method: a slot instantiated up front carries a whole component that follows the cursor,
|
||||
// while a point-by-point slot only stretches once the first point has been clicked.
|
||||
boolean refresh;
|
||||
if (instantiationManager.getComponentSlot() != null
|
||||
&& instantiationManager.getFirstControlPoint() == null) {
|
||||
refresh =
|
||||
instantiationManager.updateSingleClick(previousScaledPoint, isSnapToGrid(),
|
||||
currentProject.getGridSpacing());
|
||||
} else {
|
||||
refresh = instantiationManager.updatePointByPoint(previousScaledPoint);
|
||||
}
|
||||
if (refresh) {
|
||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||
|
||||
@@ -82,7 +82,8 @@ public class StatusBar extends JPanel implements IPlugIn {
|
||||
private static final String HOLD_TO_UNSTUCK = LangUtil.translate("hold %s and drag to unstick from");
|
||||
private static final String SELECTION = LangUtil.translate("Selection");
|
||||
private static final String DRAG_POINTS_OF = LangUtil.translate("Drag control point(s) of");
|
||||
private static final String DRAG_TO_PLACE_A_NEW = LangUtil.translate("Drag the mouse over the canvas to place a new");
|
||||
private static final String DRAG_TO_PLACE_A_NEW =
|
||||
LangUtil.translate("Click or drag over the canvas to place a new");
|
||||
private static final String ZOOM = LangUtil.translate("Zoom");
|
||||
private static final String SELECTION_SIZE = LangUtil.translate("Selection Size");
|
||||
private static final String SELECTION_IS_EMPTY = LangUtil.translate("Selection is empty.");
|
||||
|
||||
+13
@@ -94,6 +94,19 @@ public class ComponentButtonFactory {
|
||||
|
||||
button.addMouseListener(new MouseAdapter() {
|
||||
|
||||
/**
|
||||
* Runs after the button has already fired its action for this click, so re-arming the slot
|
||||
* here is what decides the mode: a double click instantiates the component up front so that
|
||||
* it follows the cursor and drops in a single gesture, the way dragging it onto the canvas
|
||||
* does, instead of asking for a point at a time.
|
||||
*/
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() > 1) {
|
||||
plugInPort.setNewComponentTypeSlot(componentType, null, null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (e.getButton() == MouseEvent.BUTTON3) {
|
||||
|
||||
@@ -123,13 +123,7 @@ public class CustomTreeModel implements TreeModel {
|
||||
if (fav.getType() == FavoriteType.Component) {
|
||||
ComponentType type = this.typesByClass.get(fav.getName());
|
||||
if (this.searchText == null || type.getName().toLowerCase().contains(this.searchText)) {
|
||||
visibleTypes.add(new TreeNode(type, new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
plugInPort.setNewComponentTypeSlot(type, null, null, false);
|
||||
}
|
||||
}));
|
||||
visibleTypes.add(new TreeNode(type, createComponentClickListener(type)));
|
||||
}
|
||||
} else {
|
||||
// block
|
||||
@@ -189,13 +183,7 @@ public class CustomTreeModel implements TreeModel {
|
||||
if (type == null)
|
||||
continue;
|
||||
if (this.searchText == null || type.getName().toLowerCase().contains(this.searchText)) {
|
||||
visibleTypes.add(new TreeNode(type, new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
plugInPort.setNewComponentTypeSlot(type, null, null, false);
|
||||
}
|
||||
}));
|
||||
visibleTypes.add(new TreeNode(type, createComponentClickListener(type)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,17 +218,29 @@ public class CustomTreeModel implements TreeModel {
|
||||
|| category.toLowerCase().contains(this.searchText.toLowerCase()) ||
|
||||
|
||||
typeMatches(this.searchText, type))
|
||||
visibleTypes.add(new TreeNode(type, new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
plugInPort.setNewComponentTypeSlot(type, null, null, false);
|
||||
}
|
||||
}));
|
||||
visibleTypes.add(new TreeNode(type, createComponentClickListener(type)));
|
||||
this.visibleLeaves.put(category, visibleTypes);
|
||||
return visibleTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Arms the slot for the specified type. A double click instantiates the component up front so
|
||||
* that it follows the cursor and drops in a single gesture, the way dragging it onto the canvas
|
||||
* does, instead of asking for a point at a time.
|
||||
*
|
||||
* @param type
|
||||
* @return listener to attach to the tree node.
|
||||
*/
|
||||
private MouseAdapter createComponentClickListener(ComponentType type) {
|
||||
return new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
plugInPort.setNewComponentTypeSlot(type, null, null, e != null && e.getClickCount() > 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private boolean typeMatches(String searchText, ComponentType type) {
|
||||
if (searchText == null || searchText.isEmpty())
|
||||
return true;
|
||||
|
||||
@@ -258,17 +258,15 @@ public class TreePanel extends JPanel {
|
||||
/**
|
||||
* Prefer release over click: {@code mouseClicked} is not posted if the cursor moves
|
||||
* between press and release (common with DnD or hand jitter), while selection may still
|
||||
* change — then re-clicks on the same row fire no selection event.
|
||||
* change - then re-clicks on the same row fire no selection event. Every release is
|
||||
* forwarded rather than only the first, so that the listener can tell a double click from
|
||||
* a single one; re-arming the slot on the second release is harmless.
|
||||
*/
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (SwingUtilities.isRightMouseButton(e) || e.isPopupTrigger()) {
|
||||
return;
|
||||
}
|
||||
if (e.getClickCount() != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
TreePath path = tree.getPathForLocation(e.getX(), e.getY());
|
||||
if (path == null) {
|
||||
path = tree.getClosestPathForLocation(e.getX(), e.getY());
|
||||
|
||||
Reference in New Issue
Block a user