1 /******************************************************************************* 2 * Copyright (c) 2010, 2018 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 ******************************************************************************/ 14 15 package org.eclipse.e4.ui.workbench.addons.minmax; 16 17 import org.eclipse.e4.ui.model.application.ui.menu.MToolControl; 18 import org.eclipse.swt.SWT; 19 import org.eclipse.swt.events.MouseAdapter; 20 import org.eclipse.swt.events.MouseEvent; 21 import org.eclipse.swt.events.MouseTrackListener; 22 import org.eclipse.swt.graphics.Point; 23 import org.eclipse.swt.graphics.Rectangle; 24 import org.eclipse.swt.widgets.Composite; 25 import org.eclipse.swt.widgets.Control; 26 import org.eclipse.swt.widgets.Layout; 27 28 /** 29 * 30 */ 31 public class TrimPaneLayout extends Layout { 32 private static int BORDER_WIDTH = 4; 33 private static final Rectangle EMPTY_RECT = new Rectangle(0, 0, 0, 0); 34 private int fixedCorner; 35 36 public Rectangle hSizingRect = EMPTY_RECT; 37 public Rectangle vSizingRect = EMPTY_RECT; 38 public Rectangle cornerRect = EMPTY_RECT; 39 private Rectangle clientRect = EMPTY_RECT; 40 private boolean resizeInstalled = false; 41 42 private static int NOT_SIZING = 0; 43 private static int HORIZONTAL_SIZING = 1; 44 private static int VERTICAL_SIZING = 2; 45 private static int CORNER_SIZING = 3; 46 47 int trackState = SWT.NONE; 48 protected Point curPos; 49 private MToolControl toolControl; 50 TrimPaneLayout(MToolControl toolControl, int barSide)51 public TrimPaneLayout(MToolControl toolControl, int barSide) { 52 this.toolControl = toolControl; 53 this.fixedCorner = barSide; 54 } 55 56 @Override computeSize(Composite composite, int wHint, int hHint, boolean flushCache)57 protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { 58 return new Point(600, 400); 59 } 60 61 @Override layout(Composite composite, boolean flushCache)62 protected void layout(Composite composite, boolean flushCache) { 63 installResize(composite); 64 65 if (composite.getChildren().length != 1) { 66 return; 67 } 68 69 if (fixedCorner == SWT.NONE) { 70 return; 71 } 72 73 Rectangle bounds = composite.getBounds(); 74 75 if (isFixed(SWT.TOP)) { 76 if (isFixed(SWT.RIGHT)) { 77 hSizingRect = new Rectangle(0, 0, BORDER_WIDTH, bounds.height - BORDER_WIDTH); 78 vSizingRect = new Rectangle(BORDER_WIDTH, bounds.height - BORDER_WIDTH, 79 bounds.width - BORDER_WIDTH, BORDER_WIDTH); 80 cornerRect = new Rectangle(0, bounds.height - BORDER_WIDTH, BORDER_WIDTH, 81 BORDER_WIDTH); 82 clientRect = new Rectangle(BORDER_WIDTH, 0, bounds.width - BORDER_WIDTH, 83 bounds.height - BORDER_WIDTH); 84 } else { 85 hSizingRect = new Rectangle(bounds.width - BORDER_WIDTH, 0, BORDER_WIDTH, 86 bounds.height - BORDER_WIDTH); 87 vSizingRect = new Rectangle(0, bounds.height - BORDER_WIDTH, bounds.width 88 - BORDER_WIDTH, BORDER_WIDTH); 89 cornerRect = new Rectangle(bounds.width - BORDER_WIDTH, bounds.height 90 - BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH); 91 clientRect = new Rectangle(0, 0, bounds.width - BORDER_WIDTH, bounds.height 92 - BORDER_WIDTH); 93 } 94 } else if (isFixed(SWT.BOTTOM)) { 95 if (isFixed(SWT.RIGHT)) { 96 hSizingRect = new Rectangle(0, BORDER_WIDTH, BORDER_WIDTH, bounds.height 97 - BORDER_WIDTH); 98 vSizingRect = new Rectangle(BORDER_WIDTH, 0, bounds.width - BORDER_WIDTH, 99 BORDER_WIDTH); 100 cornerRect = new Rectangle(0, 0, BORDER_WIDTH, BORDER_WIDTH); 101 clientRect = new Rectangle(BORDER_WIDTH, BORDER_WIDTH, bounds.width - BORDER_WIDTH, 102 bounds.height - BORDER_WIDTH); 103 } else { 104 hSizingRect = new Rectangle(bounds.width - BORDER_WIDTH, BORDER_WIDTH, 105 BORDER_WIDTH, bounds.height - BORDER_WIDTH); 106 vSizingRect = new Rectangle(0, 0, bounds.width - BORDER_WIDTH, BORDER_WIDTH); 107 cornerRect = new Rectangle(bounds.width - BORDER_WIDTH, 0, BORDER_WIDTH, 108 BORDER_WIDTH); 109 clientRect = new Rectangle(0, BORDER_WIDTH, bounds.width - BORDER_WIDTH, 110 bounds.height - BORDER_WIDTH); 111 } 112 } 113 Control child = composite.getChildren()[0]; 114 child.setBounds(clientRect); 115 } 116 installResize(final Composite composite)117 private void installResize(final Composite composite) { 118 if (resizeInstalled) { 119 return; 120 } 121 122 composite.addMouseMoveListener(e -> { 123 Point p = e.display.getCursorLocation(); 124 if (trackState == NOT_SIZING) { 125 setCursor(composite, new Point(e.x, e.y)); 126 } else if (trackState == HORIZONTAL_SIZING) { 127 dragHorizontal(composite, p); 128 } else if (trackState == VERTICAL_SIZING) { 129 dragVertical(composite, p); 130 } else if (trackState == CORNER_SIZING) { 131 dragCorner(composite, p); 132 } 133 }); 134 135 composite.addMouseListener(new MouseAdapter() { 136 137 @Override 138 public void mouseUp(MouseEvent e) { 139 composite.setCapture(false); 140 141 // Persist the current size 142 Point size = composite.getSize(); 143 toolControl.getPersistedState() 144 .put(TrimStack.STATE_XSIZE, Integer.toString(size.x)); 145 toolControl.getPersistedState() 146 .put(TrimStack.STATE_YSIZE, Integer.toString(size.y)); 147 148 trackState = NOT_SIZING; 149 } 150 151 @Override 152 public void mouseDown(MouseEvent e) { 153 Point p = new Point(e.x, e.y); 154 if (hSizingRect.contains(p)) { 155 curPos = e.display.getCursorLocation(); 156 trackState = HORIZONTAL_SIZING; 157 composite.setCapture(true); 158 } else if (vSizingRect.contains(p)) { 159 curPos = e.display.getCursorLocation(); 160 trackState = VERTICAL_SIZING; 161 composite.setCapture(true); 162 } else if (cornerRect.contains(p)) { 163 curPos = e.display.getCursorLocation(); 164 trackState = CORNER_SIZING; 165 composite.setCapture(true); 166 } 167 } 168 }); 169 170 composite.addMouseTrackListener(MouseTrackListener.mouseExitAdapter(e -> { 171 Composite comp = (Composite) e.widget; 172 comp.setCursor(null); 173 })); 174 175 resizeInstalled = true; 176 } 177 178 /** 179 * @param p 180 */ setCursor(Composite composite, Point p)181 protected void setCursor(Composite composite, Point p) { 182 if (hSizingRect.contains(p)) { 183 composite.setCursor(composite.getDisplay().getSystemCursor(SWT.CURSOR_SIZEWE)); 184 } else if (vSizingRect.contains(p)) { 185 composite.setCursor(composite.getDisplay().getSystemCursor(SWT.CURSOR_SIZENS)); 186 } else if (cornerRect.contains(p)) { 187 if (isFixed(SWT.TOP)) { 188 if (isFixed(SWT.RIGHT)) { 189 composite.setCursor(composite.getDisplay().getSystemCursor(SWT.CURSOR_SIZESW)); 190 } else { 191 composite.setCursor(composite.getDisplay().getSystemCursor(SWT.CURSOR_SIZESE)); 192 } 193 } else if (isFixed(SWT.BOTTOM)) { 194 if (isFixed(SWT.RIGHT)) { 195 composite.setCursor(composite.getDisplay().getSystemCursor(SWT.CURSOR_SIZESE)); 196 } else { 197 composite.setCursor(composite.getDisplay().getSystemCursor(SWT.CURSOR_SIZESW)); 198 } 199 } 200 } else { 201 composite.setCursor(null); 202 } 203 } 204 dragCorner(Composite composite, Point p)205 protected void dragCorner(Composite composite, Point p) { 206 int dx = p.x - curPos.x; 207 int dy = p.y - curPos.y; 208 Rectangle bounds = composite.getBounds(); 209 210 if (isFixed(SWT.RIGHT)) { 211 bounds.x += dx; 212 bounds.width -= dx; 213 } else { 214 bounds.width += dx; 215 } 216 217 if (isFixed(SWT.BOTTOM)) { 218 bounds.y += dy; 219 bounds.height -= dy; 220 } else { 221 bounds.height += dy; 222 } 223 224 composite.setBounds(bounds); 225 composite.getDisplay().update(); 226 227 curPos = p; 228 } 229 dragVertical(Composite composite, Point p)230 protected void dragVertical(Composite composite, Point p) { 231 int dy = p.y - curPos.y; 232 Rectangle bounds = composite.getBounds(); 233 if (isFixed(SWT.BOTTOM)) { 234 bounds.y += dy; 235 bounds.height -= dy; 236 } else { 237 bounds.height += dy; 238 } 239 240 composite.setBounds(bounds); 241 composite.getDisplay().update(); 242 243 curPos = p; 244 } 245 dragHorizontal(Composite composite, Point p)246 protected void dragHorizontal(Composite composite, Point p) { 247 int dx = p.x - curPos.x; 248 Rectangle bounds = composite.getBounds(); 249 if (isFixed(SWT.RIGHT)) { 250 bounds.x += dx; 251 bounds.width -= dx; 252 } else { 253 bounds.width += dx; 254 } 255 256 composite.setBounds(bounds); 257 composite.getDisplay().update(); 258 259 curPos = p; 260 } 261 isFixed(int swtSide)262 private boolean isFixed(int swtSide) { 263 return (fixedCorner & swtSide) != 0; 264 } 265 } 266