From b647f2e167b8c038df2c47a5d0ebf128a0f83c35 Mon Sep 17 00:00:00 2001 From: Patrick Ziegler Date: Sun, 15 Feb 2026 21:14:05 +0100 Subject: [PATCH] Add `DragTracker` for `PropertyEditPart`s #1314 This moves the logic for clicking on a property to this new drag-tracker, as well as the actual edit-part. By doing so, we have much more control over the figure under the cursor, which is needed because we distinguish between title and value figure. Clicking on an edit-part performs a `SELECTION` request. This request closes the current cell editor and opens a new cell editor for the selected property (but only if over the value figure). Closes https://github.com/eclipse-windowbuilder/windowbuilder/issues/1314 --- .../model/property/table/PropertyTable.java | 49 +++---------- .../editparts/AbstractPropertyEditPart.java | 9 ++- .../table/editparts/PropertyEditPart.java | 30 +++++++- .../editparts/PropertyEditPartTracker.java | 68 +++++++++++++++++++ 4 files changed, 114 insertions(+), 42 deletions(-) create mode 100644 org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/editparts/PropertyEditPartTracker.java diff --git a/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/PropertyTable.java b/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/PropertyTable.java index 1d9d8687d..37a289440 100644 --- a/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/PropertyTable.java +++ b/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/PropertyTable.java @@ -34,7 +34,6 @@ import org.eclipse.gef.EditDomain; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPartViewer; -import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; @@ -204,10 +203,10 @@ private void setActiveEditorBounds() { org.eclipse.swt.graphics.Rectangle bounds; { PropertyEditPart editPart = getEditPartForModel(m_activePropertyInfo); - Rectangle figureBounds = getAbsoluteBounds(editPart); - int x = getSplitter() + 1; + Rectangle figureBounds = getEditorBounds(editPart); + int x = figureBounds.left(); int y = figureBounds.top(); - int width = getControl().getClientArea().width - x - MARGIN_RIGHT; + int width = figureBounds.width() - MARGIN_RIGHT; int height = figureBounds.height() - MARGIN_BOTTOM; bounds = new org.eclipse.swt.graphics.Rectangle(x, y, width, height); } @@ -246,11 +245,11 @@ public void handleException(Throwable e) { //////////////////////////////////////////////////////////////////////////// /** - * @return the bounds of the given edit part relative to the top right corner of - * the viewport. + * @return the bounds of editor for the given edit part, relative to the top + * right corner of the viewport. */ - private static Rectangle getAbsoluteBounds(GraphicalEditPart editPart) { - IFigure figure = editPart.getFigure(); + private static Rectangle getEditorBounds(PropertyEditPart editPart) { + IFigure figure = editPart.getFigure().getChildren().get(1); Rectangle bounds = figure.getBounds().getCopy(); figure.translateToAbsolute(bounds); return bounds; @@ -280,25 +279,6 @@ private boolean isLocationSplitter(int x) { return Math.abs(getSplitter() - x) < 2; } - /** - * @return true if given x is on value part of - * property. - */ - private boolean isLocationValue(int x) { - return x > getSplitter() + 2; - } - - /** - * @param x the {@link PropertyTable} relative coordinate. - * @param y the {@link PropertyTable} relative coordinate. - * - * @return the location relative to the value part of property. - */ - private Point getValueRelativeLocation(int x, int y) { - GraphicalEditPart editPart = (GraphicalEditPart) findObjectAt(new Point(x, y)); - return new Point(x - (getSplitter() + 2), getAbsoluteBounds(editPart).top()); - } - /** * The height for a row, based on the font height of the parent composite. */ @@ -532,19 +512,7 @@ public class PropertyEditDomain extends EditDomain { @Override public void mouseDown(MouseEvent event, EditPartViewer viewer) { m_splitterResizing = event.button == 1 && m_properties != null && isLocationSplitter(event.x); - // click in property - if (!m_splitterResizing && findObjectAt(new Point(event.x, event.y)) instanceof PropertyEditPart editPart) { - // prepare property - select(editPart); - Property property = m_activePropertyInfo.getProperty(); - // de-activate current editor - deactivateEditor(true); - getControl().redraw(); - // activate editor - if (isLocationValue(event.x)) { - activateEditor(property, getValueRelativeLocation(event.x, event.y)); - } - } + super.mouseDown(event, viewer); } @Override @@ -573,6 +541,7 @@ public void mouseUp(MouseEvent event, EditPartViewer viewer) { } } } + super.mouseUp(event, viewer); } @Override diff --git a/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/editparts/AbstractPropertyEditPart.java b/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/editparts/AbstractPropertyEditPart.java index 0d3fa3b63..fa5a7c9f5 100644 --- a/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/editparts/AbstractPropertyEditPart.java +++ b/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/editparts/AbstractPropertyEditPart.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2025 Patrick Ziegler and others. + * Copyright (c) 2025, 2026 Patrick Ziegler and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -17,6 +17,8 @@ import org.eclipse.wb.internal.core.utils.ui.DrawUtils; import org.eclipse.draw2d.ColorConstants; +import org.eclipse.gef.DragTracker; +import org.eclipse.gef.Request; import org.eclipse.gef.editparts.AbstractGraphicalEditPart; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; @@ -72,4 +74,9 @@ protected void createEditPolicies() { public PropertyTable getViewer() { return (PropertyTable) super.getViewer(); } + + @Override + public DragTracker getDragTracker(Request request) { + return null; + } } diff --git a/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/editparts/PropertyEditPart.java b/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/editparts/PropertyEditPart.java index 7657ecd03..2adc8d7ce 100644 --- a/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/editparts/PropertyEditPart.java +++ b/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/editparts/PropertyEditPart.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2025 Patrick Ziegler and others. + * Copyright (c) 2025, 2026 Patrick Ziegler and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -37,7 +37,11 @@ import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Insets; import org.eclipse.draw2d.geometry.Point; +import org.eclipse.gef.DragTracker; import org.eclipse.gef.EditPart; +import org.eclipse.gef.Request; +import org.eclipse.gef.RequestConstants; +import org.eclipse.gef.requests.SelectionRequest; import org.eclipse.jface.resource.FontDescriptor; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.swt.SWT; @@ -154,6 +158,30 @@ public PropertyInfo getModel() { return (PropertyInfo) super.getModel(); } + @Override + public DragTracker getDragTracker(Request request) { + return new PropertyEditPartTracker(this); + } + + @Override + public void performRequest(Request request) { + if (RequestConstants.REQ_SELECTION == request.getType()) { + performSelection((SelectionRequest) request); + } + } + + private void performSelection(SelectionRequest request) { + // de-activate current editor + getViewer().deactivateEditor(true); + getViewer().getControl().redraw(); + // activate editor + Point mouseLocation = request.getLocation().getCopy(); + getFigure().translateToRelative(mouseLocation); + if (valueFigure.containsPoint(mouseLocation)) { + getViewer().activateEditor(getProperty(), mouseLocation); + } + } + @Override protected IFigure createFigure() { SeparatorBorder border = new SeparatorBorder(new Insets(0, 0, MARGIN_BOTTOM, 1), PositionConstants.BOTTOM); diff --git a/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/editparts/PropertyEditPartTracker.java b/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/editparts/PropertyEditPartTracker.java new file mode 100644 index 000000000..4c6d41e99 --- /dev/null +++ b/org.eclipse.wb.core/src/org/eclipse/wb/internal/core/model/property/table/editparts/PropertyEditPartTracker.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2026 Patrick Ziegler and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Patrick Ziegler - initial API and implementation + *******************************************************************************/ +package org.eclipse.wb.internal.core.model.property.table.editparts; + +import org.eclipse.wb.internal.core.model.property.table.PropertyTable; + +import org.eclipse.gef.DragTracker; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.requests.SelectionRequest; +import org.eclipse.gef.tools.TargetingTool; + +/** + * DragTracker used to select, edit, and open {@link PropertyEditPart}s. + */ +public class PropertyEditPartTracker extends TargetingTool implements DragTracker { + private EditPart owner; + + /** + * Constructs a new {@link PropertyEditPartTracker} with the given edit part as + * the source. + * + * @param owner the source edit part + */ + public PropertyEditPartTracker(EditPart owner) { + this.owner = owner; + } + + /** + * Returns {@code true} if cursor is on splitter. + */ + private boolean isLocationSplitter() { + if (getCurrentViewer() instanceof PropertyTable propertyTable) { + return Math.abs(propertyTable.getSplitter() - getLocation().x) < 2; + } + return false; + } + + @Override + protected boolean handleButtonDown(int button) { + if (isLocationSplitter() || button != 1) { + return false; + } + + getCurrentViewer().select(owner); + + SelectionRequest request = new SelectionRequest(); + request.setType(REQ_SELECTION); + request.setLocation(getLocation()); + owner.performRequest(request); + + return true; + } + + @Override + protected String getCommandName() { + return "Property Tracker";//$NON-NLS-1$ + } +}