From f1cfb52102585feb61c8c8f8bc00cf8b60edf38b Mon Sep 17 00:00:00 2001 From: Starryi Date: Thu, 1 Jul 2021 14:45:31 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-54116=20=E8=AE=BE=E8=AE=A1=E5=99=A8?= =?UTF-8?q?=E7=BB=9D=E5=AF=B9=E5=B8=83=E5=B1=80=E5=86=85=E5=8F=AF=E9=94=81?= =?UTF-8?q?=E5=AE=9A=E7=BB=84=E4=BB=B6=E5=AE=BD=E9=AB=98=E6=AF=94=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 绝对布局内的组件,按下Shift键拖拽改变组件尺寸或在设计器右侧栏 编辑组件尺寸大小时,可以保持组件宽高比例不变,优化用户体验 按下Shift键鼠标拖拽改变组件尺寸时锁定宽高比例的逻辑, 也对参数面板内控件和表格浮动元素生效 --- .../widget/WidgetBoundsPaneFactory.java | 48 ++++-- .../images/buttonicon/icon_lock_disabled.png | Bin 0 -> 225 bytes .../images/buttonicon/icon_lock_enabled.png | Bin 0 -> 229 bytes .../buttonicon/icon_unlock_disabled.png | Bin 0 -> 226 bytes .../images/buttonicon/icon_unlock_enabled.png | Bin 0 -> 229 bytes .../beans/location/AccessDirection.java | 5 + .../designer/beans/location/Bottom.java | 11 ++ .../design/designer/beans/location/Left.java | 11 ++ .../designer/beans/location/LeftBottom.java | 20 +++ .../designer/beans/location/LeftTop.java | 23 +++ .../design/designer/beans/location/Right.java | 13 ++ .../designer/beans/location/RightBottom.java | 18 +++ .../designer/beans/location/RightTop.java | 20 +++ .../design/designer/beans/location/Top.java | 11 ++ .../designer/beans/models/StateModel.java | 11 ++ .../mainframe/EditingMouseListener.java | 7 +- .../mainframe/FormEditorKeyListener.java | 12 +- .../fr/design/mainframe/FormSelection.java | 13 ++ .../component/WidgetAbsoluteBoundPane.java | 6 +- .../designer/component/WidgetBoundPane.java | 149 ++++++++++++++++-- .../java/com/fr/grid/GridMouseAdapter.java | 81 ++++++++-- 21 files changed, 423 insertions(+), 36 deletions(-) create mode 100644 designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_lock_disabled.png create mode 100644 designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_lock_enabled.png create mode 100644 designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_unlock_disabled.png create mode 100644 designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_unlock_enabled.png diff --git a/designer-base/src/main/java/com/fr/design/widget/WidgetBoundsPaneFactory.java b/designer-base/src/main/java/com/fr/design/widget/WidgetBoundsPaneFactory.java index 9b6e7b5c8..ae3dfc255 100644 --- a/designer-base/src/main/java/com/fr/design/widget/WidgetBoundsPaneFactory.java +++ b/designer-base/src/main/java/com/fr/design/widget/WidgetBoundsPaneFactory.java @@ -10,6 +10,7 @@ import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import javax.swing.BorderFactory; +import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.SwingConstants; import java.awt.BorderLayout; @@ -45,23 +46,28 @@ public class WidgetBoundsPaneFactory { private static final int RIGHT_PANE_WIDTH = 145; - public static UIExpandablePane createBoundsPane(UISpinner width, UISpinner height) { + public static UIExpandablePane createBoundsPane(UISpinner width, UISpinner height, JComponent ratioLocked) { JPanel boundsPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); double f = TableLayout.FILL; double p = TableLayout.PREFERRED; Component[][] components = new Component[][]{ - new Component[]{FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Basic_Component_Size")), createRightPane(width, height)}, + new Component[]{FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Basic_Component_Size")), + ratioLocked != null ? createRightPane(width, ratioLocked, height) : createRightPane(width, height)}, new Component[]{null, createRightPane(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Tree_Width"), SwingConstants.CENTER), new UILabel(Toolkit.i18nText("Fine-Design_Basic_Tree_Height"), SwingConstants.CENTER))}, }; double[] rowSize = {p, p}; double[] columnSize = {f, RIGHT_PANE_WIDTH}; - int[][] rowCount = {{1, 1}, {1, 1}}; + int[][] rowCount = ratioLocked != null ? new int[][]{{1, 1}, {1, 1, 1}} : new int[][]{{1, 1}, {1, 1}}; final JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W5, IntervalConstants.INTERVAL_L6); panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); boundsPane.add(panel); return new UIExpandablePane(Toolkit.i18nText("Fine-Design_Form_Coords_And_Size"), 280, 24, boundsPane); } + public static UIExpandablePane createBoundsPane(UISpinner width, UISpinner height) { + return createBoundsPane(width, height, null); + } + public static JPanel createRightPane(Component com1, Component com2) { double f = TableLayout.FILL; double p = TableLayout.PREFERRED; @@ -74,21 +80,41 @@ public class WidgetBoundsPaneFactory { return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_L6, IntervalConstants.INTERVAL_L1); } - public static UIExpandablePane createAbsoluteBoundsPane(UISpinner x, UISpinner y, UISpinner width, UISpinner height, NameAttribute nameAttribute) { + public static JPanel createRightPane(Component com1, Component com2, Component com3) { + double f = TableLayout.FILL; + double p = TableLayout.PREFERRED; + double[] rowSize = {p}; + double[] columnSize = {f, 24, f}; + int[][] rowCount = {{1, 1, 1}}; + Component[][] components = new Component[][]{ + new Component[]{com1, com2, com3} + }; + return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 0, IntervalConstants.INTERVAL_L1); + } + + public static UIExpandablePane createAbsoluteBoundsPane(UISpinner x, UISpinner y, UISpinner width, UISpinner height, JComponent ratioLocked, NameAttribute nameAttribute) { double f = TableLayout.FILL; double p = TableLayout.PREFERRED; + UILabel positionLabel = FRWidgetFactory.createLineWrapLabel(nameAttribute.getPositionName()); + UILabel xLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_X_Coordinate"), SwingConstants.CENTER); + UILabel yLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Y_Coordinate"), SwingConstants.CENTER); + + UILabel sizeLabel = FRWidgetFactory.createLineWrapLabel(nameAttribute.getSizeName()); + UILabel widthLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Tree_Width"), SwingConstants.CENTER); + UILabel heightLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Tree_Height"), SwingConstants.CENTER); + Component[][] northComponents = new Component[][]{ - new Component[]{FRWidgetFactory.createLineWrapLabel(nameAttribute.getPositionName()), createRightPane(x, y)}, - new Component[]{null, createRightPane(new UILabel(Toolkit.i18nText("Fine-Design_Basic_X_Coordinate"), SwingConstants.CENTER), new UILabel(Toolkit.i18nText("Fine-Design_Basic_Y_Coordinate"), SwingConstants.CENTER))}, + new Component[]{positionLabel, ratioLocked != null ? createRightPane(x, null, y) : createRightPane(x, y)}, + new Component[]{null, ratioLocked != null ? createRightPane(xLabel, null, yLabel) : createRightPane(xLabel, yLabel)}, }; Component[][] centerComponents = new Component[][]{ - new Component[]{FRWidgetFactory.createLineWrapLabel(nameAttribute.getSizeName()), createRightPane(width, height)}, - new Component[]{null, createRightPane(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Tree_Width"), SwingConstants.CENTER), new UILabel(Toolkit.i18nText("Fine-Design_Basic_Tree_Height"), SwingConstants.CENTER))}, + new Component[]{sizeLabel, ratioLocked != null ? createRightPane(width, ratioLocked, height) : createRightPane(width, height)}, + new Component[]{null, ratioLocked != null ? createRightPane(widthLabel, null, heightLabel) : createRightPane(widthLabel, heightLabel)}, }; double[] rowSize = {p, p}; double[] columnSize = {f, RIGHT_PANE_WIDTH}; - int[][] rowCount = {{1, 1}, {1, 1}}; + int[][] rowCount = ratioLocked != null ? new int[][]{{1, 1, 1}, {1, 1, 1}} : new int[][]{{1, 1}, {1, 1}}; final JPanel northPanel = TableLayoutHelper.createGapTableLayoutPane(northComponents, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W5, IntervalConstants.INTERVAL_L6); final JPanel centerPanel = TableLayoutHelper.createGapTableLayoutPane(centerComponents, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W5, IntervalConstants.INTERVAL_L6); JPanel boundsPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); @@ -99,6 +125,10 @@ public class WidgetBoundsPaneFactory { return new UIExpandablePane(Toolkit.i18nText("Fine-Design_Form_Coords_And_Size"), 230, 24, boundsPane); } + public static UIExpandablePane createAbsoluteBoundsPane(UISpinner x, UISpinner y, UISpinner width, UISpinner height, NameAttribute nameAttribute) { + return createAbsoluteBoundsPane(x, y, width, height, null, nameAttribute); + } + public static UIExpandablePane createAbsoluteBoundsPane(UISpinner x, UISpinner y, UISpinner width, UISpinner height) { return createAbsoluteBoundsPane(x, y, width, height, NameAttribute.DEFAULT); } diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_lock_disabled.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_lock_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..b498e7c141ff6e719ef7ea3c4ba8dc33da3f7d2a GIT binary patch literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`D?D8sLoEE0Qx*sq1g)6gn8s!x zDH*xK*x=99_8k*`KHOQXo@ZoW@W;8_Fic!RGBU%+$mqkzPem~-nLqygZ2$NFKhOMg zbFB;KdNBLg{`j$jU&f-~0lPXLoEE0Qx*sq1g)6gXvUV2 znYppBsL1^9|Nr{DPn_J`mPOv*U%z&D+1p$CCF04YjT<*+vNIp9zk7fG%*&FJ^?%Y6 z6Xza1aG>Jno12$KT_h7yQvSRVBL;LggQu&X%Q~loCIA+%TQC3s literal 0 HcmV?d00001 diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_unlock_disabled.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/icon_unlock_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..6785a5130912472e8ec207c6b6707e5bb61de154 GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`D?MEtLoEE0Qx*sq1g)6QIGxeQ z%}wkT4^REm|9^k~pWfN|^yJQB^*kd3gFnvO1y(ZxWoPyD@YL+tBO~r8Wmo@i;s5{k zhnE*W_lr@##1PDHXZMbooloWm!VcI9Q?~ zosg82^!L5|Vga-N#)g0E%b%T@x%fnpL}Efp%Bybu4;Prr1*9AbB?Kl{d|*>r33Rbq Wr=OtT@&zDYFnGH9xvXXLoEE0Qx*sq1g)6QxSBC4 zDk^8roIAe%|Nr++PD%Om@xT4yNAmXjuEy;ydn>-HHGLyJv}}5|Ni~${{7L>ZhuFqFJI22MnwLfXIcHNhb53rLVETe z`|58zfe)Jxb35N+NKT%7n1_eQ%;M7ViJQ~U-%vW8*utp6@KIIo%K_OrYyo0yOVacf d1xedEGfuAe75w 0 && height4Backup > 0) { + mHeightSpinner.setValue(mWidthSpinner.getValue() * width4Backup / height4Backup, false); + } + } + }); + mHeightSpinner.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + if (isLockEnabled() && isLocked() && width4Backup > 0 && height4Backup > 0) { + mWidthSpinner.setValue(mHeightSpinner.getValue() * height4Backup / width4Backup, false); + } + } + }); + } + + @Override + public Icon getIcon() { + if (this.isLocked()) { + if (this.isLockEnabled()) { + return enabledLocked; + } else { + return disabledLocked; + } + } else { + if (this.isLockEnabled()) { + return enabledUnLocked; + } else { + return disabledUnLocked; + } + } + } + + public void setLocked(boolean locked) { + this.setSelected(locked); + } + + public boolean isLocked() { + return this.isSelected(); + } + + public boolean isLockEnabled() { + return this.isEnabled(); + } + + public void setLockEnabled(boolean enabled) { + this.setEnabled(enabled); + } + + public void populate(XCreator creator) { + Rectangle bounds = new Rectangle(creator.getBounds()); + mCreator = creator; + width4Backup = bounds.width; + height4Backup = bounds.height; + Widget widget = creator.toData(); + setLocked(widget.isAspectRatioLocked()); + } + } } diff --git a/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java b/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java index b0f91a902..b6dc8bc4a 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java +++ b/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java @@ -75,6 +75,8 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous private int resolution = ScreenResolution.getScreenResolution(); + private int[] resizingBackupBounds = null; + protected GridMouseAdapter(Grid grid) { this.grid = grid; } @@ -338,6 +340,7 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous } boolean isControlDown = InputEventBaseOnOS.isControlDown(evt); + boolean isShiftDown = evt.isShiftDown(); long systemCurrentTime = System.currentTimeMillis(); if (systemCurrentTime - lastMouseMoveTime <= DRAG_REFRESH_TIME) {// alex:Drag @@ -351,10 +354,10 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous return; } - doWithMouseDragged(evt.getX(), evt.getY(), isControlDown); + doWithMouseDragged(evt.getX(), evt.getY(), isControlDown, isShiftDown); } - private void doWithMouseDragged(int evtX, int evtY, boolean isControlDown) { + private void doWithMouseDragged(int evtX, int evtY, boolean isControlDown, boolean isShiftDown) { ElementCasePane reportPane = grid.getElementCasePane(); if (reportPane.mustInVisibleRange()) { @@ -366,7 +369,7 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous Selection selection = reportPane.getSelection(); if (selection instanceof FloatSelection && !DesignerMode.isAuthorityEditing()) { - doWithFloatElementDragged(evtX, evtY, (FloatSelection) selection); + doWithFloatElementDragged(evtX, evtY, (FloatSelection) selection, isShiftDown); grid.setDragType(GridUtils.DRAG_FLOAT); } else if (grid.getDragType() == GridUtils.DRAG_CELLSELECTION_BOTTOMRIGHT_CORNER && !DesignerMode.isAuthorityEditing()) { doWithCellElementDragged(evtX, evtY, (CellSelection) selection); @@ -391,36 +394,83 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous * @param fs */ - private void doWithFloatElementDragged(int evtX, int evtY, FloatSelection fs) { + private void doWithFloatElementDragged(int evtX, int evtY, FloatSelection fs, boolean aspectRatio) { ElementCase report = grid.getElementCasePane().getEditingElementCase(); // int resolution = ScreenResolution.getScreenResolution(); String floatName = fs.getSelectedFloatName(); FloatElement floatElement = report.getFloatElement(floatName); int cursorType = grid.getCursor().getType(); + int currentLeft = Math.min(oldEvtX, evtX); + int currentTop = Math.min(oldEvtY, evtY); + int currentRight = Math.max(oldEvtX, evtX); + int currentBottom = Math.max(oldEvtY, evtY); + int currentWidth = currentRight - currentLeft; + int currentHeight = currentBottom - currentTop; + + int backupWidth= resizingBackupBounds[2]; + int backupHeight= resizingBackupBounds[3]; + if (cursorType == Cursor.NW_RESIZE_CURSOR || cursorType == Cursor.NE_RESIZE_CURSOR || cursorType == Cursor.SE_RESIZE_CURSOR || cursorType == Cursor.SW_RESIZE_CURSOR) { + if (aspectRatio) { + double currentDiagonal = Math.pow(currentWidth, 2) + Math.pow(currentHeight, 2); + double backupDiagonal = Math.pow(backupWidth, 2) + Math.pow(backupHeight, 2); + + int newWidth = (int) (Math.sqrt((currentDiagonal / backupDiagonal) * (Math.pow(backupWidth, 2)))); + int newHeight = (int) (Math.sqrt((currentDiagonal / backupDiagonal) * (Math.pow(backupHeight, 2)))); + + if (cursorType == Cursor.NW_RESIZE_CURSOR) { + currentLeft = currentRight - newWidth; + currentTop = currentBottom - newHeight; + } else if (cursorType == Cursor.NE_RESIZE_CURSOR) { + currentRight = currentLeft + newWidth; + currentTop = currentBottom - newHeight; + } else if (cursorType == Cursor.SW_RESIZE_CURSOR) { + currentLeft = currentRight - newWidth; + currentBottom = currentTop + newHeight; + } else if (cursorType == Cursor.SE_RESIZE_CURSOR){ + currentRight = currentLeft + newWidth; + currentBottom = currentTop + newHeight; + } + } + DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); - FU floatX1_fu = FU.valueOfPix(Math.min(oldEvtX, evtX), resolution); - FU floatY1_fu = FU.valueOfPix(Math.min(oldEvtY, evtY), resolution); + + FU floatX1_fu = FU.valueOfPix(currentLeft, resolution); + FU floatY1_fu = FU.valueOfPix(currentTop, resolution); FU leftDistance = floatX1_fu.add(columnWidthList.getRangeValue(0, grid.getHorizontalValue())); FU topDistance = floatY1_fu.add(rowHeightList.getRangeValue(0, grid.getVerticalValue())); floatElement.setLeftDistance(leftDistance); floatElement.setTopDistance(topDistance); - floatElement.setWidth(FU.valueOfPix(Math.max(oldEvtX, evtX), resolution).subtract(floatX1_fu)); - floatElement.setHeight(FU.valueOfPix(Math.max(oldEvtY, evtY), resolution).subtract(floatY1_fu)); + floatElement.setWidth(FU.valueOfPix(currentRight, resolution).subtract(floatX1_fu)); + floatElement.setHeight(FU.valueOfPix(currentBottom, resolution).subtract(floatY1_fu)); } else if (cursorType == Cursor.S_RESIZE_CURSOR || cursorType == Cursor.N_RESIZE_CURSOR) { DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); - FU floatY1_fu = FU.valueOfPix(Math.min(oldEvtY, evtY), resolution); + FU floatY1_fu = FU.valueOfPix(currentTop, resolution); FU topDistance = floatY1_fu.add(rowHeightList.getRangeValue(0, grid.getVerticalValue())); floatElement.setTopDistance(topDistance); - floatElement.setHeight(FU.valueOfPix(Math.max(oldEvtY, evtY), resolution).subtract(floatY1_fu)); + floatElement.setHeight(FU.valueOfPix(currentBottom, resolution).subtract(floatY1_fu)); + + if (aspectRatio) { + currentWidth = backupWidth * currentHeight / backupHeight; + currentRight = currentLeft + currentWidth; + FU floatX1_fu = FU.valueOfPix(currentLeft, resolution); + floatElement.setWidth(FU.valueOfPix(currentRight, resolution).subtract(floatX1_fu)); + } } else if (cursorType == Cursor.W_RESIZE_CURSOR || cursorType == Cursor.E_RESIZE_CURSOR) { DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); - FU floatX1_fu = FU.valueOfPix(Math.min(oldEvtX, evtX), resolution); + FU floatX1_fu = FU.valueOfPix(currentLeft, resolution); FU leftDistance = floatX1_fu.add(columnWidthList.getRangeValue(0, grid.getHorizontalValue())); floatElement.setLeftDistance(leftDistance); - floatElement.setWidth(FU.valueOfPix(Math.max(oldEvtX, evtX), resolution).subtract(floatX1_fu)); + floatElement.setWidth(FU.valueOfPix(currentRight, resolution).subtract(floatX1_fu)); + + if (aspectRatio) { + currentHeight = backupHeight * currentWidth / backupWidth; + currentBottom = currentTop + currentHeight; + FU floatY1_fu = FU.valueOfPix(currentTop, resolution); + floatElement.setHeight(FU.valueOfPix(currentBottom, resolution).subtract(floatY1_fu)); + } } else if (cursorType == Cursor.MOVE_CURSOR) { DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report); DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report); @@ -799,6 +849,13 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous } else if (cursorType == Cursor.E_RESIZE_CURSOR) { setOld_X_AndOld_Y(floatArray[0], floatArray[1]); } + + if (Cursor.SW_RESIZE_CURSOR <= cursorType && cursorType <= Cursor.E_RESIZE_CURSOR) { + resizingBackupBounds = new int[] { + (int) floatArray[0], (int)floatArray[1], + (int) floatArray[2] - (int) floatArray[0], (int) floatArray[3] - (int) floatArray[1] + }; + } } private void setOld_X_AndOld_Y(double x, double y) {