Skip to content

Commit d538ee2

Browse files
committed
Adjust direct edit text control bounds for Windows scaling
- On Windows calling referenceFigure.translateToAbsolute(rect) multiplies the bounds of the figure by the display scaling. So we need to also multiply other calculations by this factor including the trimWidth and minimum width. - Add FigureUtils#getDisplayScale() - In FigureUtils#getFigureScale consider that scaling could also include the display scale on Windows so check for parent AutoscaleFreeformViewport. This is not ideal but will suffice for now.
1 parent ee45082 commit d538ee2

2 files changed

Lines changed: 76 additions & 48 deletions

File tree

com.archimatetool.editor/src/com/archimatetool/editor/diagram/directedit/MultiLineTextDirectEditManager.java

Lines changed: 58 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
import org.eclipse.jface.viewers.CellEditor;
99
import org.eclipse.jface.viewers.TextCellEditor;
1010
import org.eclipse.swt.SWT;
11-
import org.eclipse.swt.events.TraverseEvent;
1211
import org.eclipse.swt.events.TraverseListener;
1312
import org.eclipse.swt.graphics.Point;
1413
import org.eclipse.swt.widgets.Composite;
1514
import org.eclipse.swt.widgets.Text;
1615

16+
import com.archimatetool.editor.diagram.figures.FigureUtils;
1717
import com.archimatetool.editor.diagram.figures.IDiagramModelObjectFigure;
1818
import com.archimatetool.editor.diagram.figures.connections.IDiagramConnectionFigure;
1919
import com.archimatetool.editor.utils.StringUtils;
@@ -57,13 +57,10 @@ public MultiLineTextDirectEditManager(GraphicalEditPart source, boolean isSingle
5757
protected CellEditor createCellEditorOn(Composite composite) {
5858
int alignment = SWT.LEFT;
5959

60-
if(getEditPart().getModel() instanceof ITextAlignment) {
61-
int ta = ((ITextAlignment)getEditPart().getModel()).getTextAlignment();
62-
if(ta == ITextAlignment.TEXT_ALIGNMENT_CENTER) {
63-
alignment = SWT.CENTER;
64-
}
65-
else if(ta == ITextAlignment.TEXT_ALIGNMENT_RIGHT) {
66-
alignment = SWT.RIGHT;
60+
if(getEditPart().getModel() instanceof ITextAlignment textAlignment) {
61+
switch(textAlignment.getTextAlignment()) {
62+
case ITextAlignment.TEXT_ALIGNMENT_CENTER -> alignment = SWT.CENTER;
63+
case ITextAlignment.TEXT_ALIGNMENT_RIGHT -> alignment = SWT.RIGHT;
6764
}
6865
}
6966

@@ -80,25 +77,21 @@ protected void initCellEditor() {
8077
Object model = getEditPart().getModel();
8178
String value = ""; //$NON-NLS-1$
8279

83-
if(model instanceof ITextContent) {
84-
value = ((ITextContent)model).getContent();
80+
if(model instanceof ITextContent textContent) {
81+
value = textContent.getContent();
8582
}
86-
else if(model instanceof INameable) {
87-
value = ((INameable)model).getName();
83+
else if(model instanceof INameable nameable) {
84+
value = nameable.getName();
8885
}
8986

9087
getCellEditor().setValue(StringUtils.safeString(value));
9188

9289
if(isSingleText) {
9390
setNormalised();
9491

95-
traverseListener = new TraverseListener() {
96-
@Override
97-
public void keyTraversed(TraverseEvent event) {
98-
if(event.detail == SWT.TRAVERSE_RETURN || event.detail == SWT.TRAVERSE_TAB_PREVIOUS
99-
|| event.detail == SWT.TRAVERSE_TAB_NEXT) {
100-
commit();
101-
}
92+
traverseListener = event -> {
93+
if(event.detail == SWT.TRAVERSE_RETURN || event.detail == SWT.TRAVERSE_TAB_PREVIOUS || event.detail == SWT.TRAVERSE_TAB_NEXT) {
94+
commit();
10295
}
10396
};
10497

@@ -122,56 +115,73 @@ protected void unhookListeners() {
122115
private class MultiLineCellEditorLocator implements CellEditorLocator {
123116
@Override
124117
public void relocate(CellEditor celleditor) {
125-
Text text = getTextControl();
118+
final Text text = getTextControl();
126119

127120
Rectangle rect = referenceFigure.getBounds().getCopy();
128-
referenceFigure.translateToAbsolute(rect);
121+
referenceFigure.translateToAbsolute(rect); // rect will be scaled to display scale on Windows
129122

123+
int trimWidth = getScaledValue(text.computeTrim(0, 0, 0, 0).width);
124+
130125
// IDiagramConnectionFigure
131126
if(getEditPart().getFigure() instanceof IDiagramConnectionFigure) {
132127
if(isSingleText) {
133-
int trimWidth = text.computeTrim(0, 0, 0, 0).width;
134128
rect.width += trimWidth;
135-
if(rect.width < 100) {
136-
rect.width = 100;
137-
}
138-
int height = text.computeSize(rect.width - trimWidth, SWT.DEFAULT).y;
139-
text.setBounds(rect.x, rect.y, rect.width, height);
129+
rect.width = Math.max(getScaledValue(100), // minimum of 100 width
130+
Math.min(getScaledValue(800), rect.width)); // maximum of 800 width
131+
rect.height = text.computeSize(rect.width - trimWidth, SWT.DEFAULT).y;
140132
}
141133
else {
142134
Point preferredSize = text.computeSize(SWT.DEFAULT, SWT.DEFAULT);
143-
text.setBounds(rect.x, rect.y, Math.max(150, rect.width), Math.max(60, preferredSize.y));
135+
rect.width = Math.max(getScaledValue(150), rect.width); // minimum of 150 width
136+
rect.height = Math.max(getScaledValue(60), preferredSize.y); // minimum of 60 height
144137
}
145138
}
146139
// IDiagramModelObjectFigure
147-
else {
140+
else if(referenceFigure instanceof IDiagramModelObjectFigure dmoFigure) {
148141
rect.x += 5;
149142

150-
// Single Text control
151143
if(isSingleText) {
152-
int height = text.computeSize(rect.width - text.computeTrim(0, 0, 0, 0).width, SWT.DEFAULT).y;
153-
154-
// Reference figure is not a Label so it's a figure box
155-
if(!(referenceFigure instanceof Label)) {
156-
// Use height of the figure box or text edit control, whichever is the smallest
157-
height = Math.min(height, rect.height);
158-
159-
// Position the y at the same y position as the figure's text control
160-
Rectangle textControlBounds = ((IDiagramModelObjectFigure)referenceFigure).getTextControl().getBounds().getCopy();
161-
((IDiagramModelObjectFigure)referenceFigure).getTextControl().translateToAbsolute(textControlBounds);
162-
163-
rect.y = textControlBounds.y;
164-
}
165-
166-
rect.height = height;
144+
int height = text.computeSize(rect.width - trimWidth, SWT.DEFAULT).y;
145+
// Use height of the figure box or text edit control, whichever is the smallest
146+
rect.height = Math.min(height, rect.height);
147+
148+
// Position the y at the same y position as the figure's text control
149+
Rectangle textControlBounds = dmoFigure.getTextControl().getBounds().getCopy();
150+
dmoFigure.getTextControl().translateToAbsolute(textControlBounds);
151+
rect.y = textControlBounds.y;
167152
}
168-
// Multi Text control
169153
else {
170154
rect.y += 5;
171155
}
172-
173-
text.setBounds(rect.x, rect.y, rect.width, rect.height);
174156
}
157+
// Label figure
158+
else if(referenceFigure instanceof Label) {
159+
rect.x += 5;
160+
161+
if(isSingleText) {
162+
rect.height = text.computeSize(rect.width - trimWidth, SWT.DEFAULT).y;
163+
}
164+
else {
165+
rect.y += 5;
166+
}
167+
}
168+
169+
text.setBounds(rect.x, rect.y, rect.width, rect.height);
170+
}
171+
172+
/**
173+
* On Windows calling Figure#translateToAbsolute(Rectangle) will also scale the width and height
174+
* of the Rectangle by the display scale so all other values need to be scaled accordingly.
175+
*
176+
* @return the value that has been scaled according to display scaling
177+
*/
178+
private int getScaledValue(int value) {
179+
// This scales by display scale and diagram zoom but we only want the display scale for the text control
180+
// Dimension d = new Dimension(value, 0);
181+
// referenceFigure.translateToAbsolute(d);
182+
// return d.width();
183+
184+
return Math.round(value * FigureUtils.getDisplayScale());
175185
}
176186
}
177187

com.archimatetool.editor/src/com/archimatetool/editor/diagram/figures/FigureUtils.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
package com.archimatetool.editor.diagram.figures;
77

8+
import org.eclipse.draw2d.AutoscaleFreeformViewport;
89
import org.eclipse.draw2d.ColorConstants;
910
import org.eclipse.draw2d.Graphics;
1011
import org.eclipse.draw2d.IFigure;
@@ -15,8 +16,11 @@
1516
import org.eclipse.swt.graphics.Device;
1617
import org.eclipse.swt.graphics.Path;
1718
import org.eclipse.swt.graphics.Pattern;
19+
import org.eclipse.swt.internal.DPIUtil;
1820
import org.eclipse.swt.widgets.Display;
1921

22+
import com.archimatetool.editor.utils.PlatformUtils;
23+
2024

2125
/**
2226
* Utils for Figures
@@ -32,12 +36,26 @@ public class FigureUtils {
3236
*/
3337
public static double getFigureScale(IFigure figure) {
3438
if(figure instanceof ScalableFigure scalableFigure) {
39+
// On Windows if parent is AutoscaleFreeformViewport then it also
40+
// applies the display scaling so we have to remove that.
41+
// This won't happen in a diagram but will in {@link com.archimatetool.editor.diagram.util.DiagramUtils#createViewer}
42+
if(scalableFigure.getParent() instanceof AutoscaleFreeformViewport) {
43+
return scalableFigure.getScale() / getDisplayScale();
44+
}
3545
return scalableFigure.getScale();
3646
}
3747

3848
return figure == null ? 1.0 : getFigureScale(figure.getParent());
3949
}
4050

51+
/**
52+
* @return the display scaling if on Windows, else return 1
53+
*/
54+
@SuppressWarnings("restriction")
55+
public static float getDisplayScale() {
56+
return PlatformUtils.isWindows() ? DPIUtil.getDeviceZoom() / 100f : 1f;
57+
}
58+
4159
/**
4260
* Gradient Direction
4361
*/

0 commit comments

Comments
 (0)