package com.swtxml.ide;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Transform;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Sash;
public class ResizableComposite extends Composite {
private static final int HORIZONTAL_SASH_HEIGHT = 30;
private static final int VERTICAL_SASH_WIDTH = 30;
private Composite innerComposite;
private GridData innerCompositeLayoutData;
public ResizableComposite(Composite parent) {
super(parent, SWT.NONE);
GridLayoutFactory.fillDefaults().numColumns(2).spacing(0, 0).applyTo(this);
this.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
innerComposite = new Composite(this, SWT.NONE);
innerCompositeLayoutData = new GridData(100, 100);
innerComposite.setLayoutData(innerCompositeLayoutData);
Sash verticalSash = new Sash(this, SWT.SMOOTH | SWT.VERTICAL);
GridDataFactory.fillDefaults().hint(VERTICAL_SASH_WIDTH, 0).applyTo(verticalSash);
verticalSash.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
innerCompositeLayoutData.widthHint = e.x;
checkLayout();
}
});
verticalSash.addPaintListener(createVerticalRulerPainter());
verticalSash.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
verticalSash.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE));
Sash horizontalSash = new Sash(this, SWT.SMOOTH);
GridDataFactory.fillDefaults().span(2, 1).hint(0, HORIZONTAL_SASH_HEIGHT).applyTo(
horizontalSash);
horizontalSash.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
innerCompositeLayoutData.heightHint = e.y;
checkLayout();
}
});
horizontalSash.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
horizontalSash.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE));
horizontalSash.addPaintListener(createHorizontalRulerPainter());
this.addControlListener(new ControlAdapter() {
@Override
public void controlResized(ControlEvent e) {
checkLayout();
}
});
}
protected void checkLayout() {
innerCompositeLayoutData.widthHint = Math.min(innerCompositeLayoutData.widthHint, this
.getBounds().width
- VERTICAL_SASH_WIDTH);
innerCompositeLayoutData.heightHint = Math.min(innerCompositeLayoutData.heightHint, this
.getBounds().height
- HORIZONTAL_SASH_HEIGHT);
layout();
Control[] children = getChildren();
for (Control control : children) {
control.redraw();
}
}
protected void resetSize() {
this.getParent().layout();
Point size = innerComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
innerCompositeLayoutData.widthHint = size.x;
innerCompositeLayoutData.heightHint = size.y;
checkLayout();
}
private PaintListener createHorizontalRulerPainter() {
return new PaintListener() {
public void paintControl(PaintEvent e) {
int w = innerComposite.getBounds().width;
if (w == 0) {
return;
}
int xStart = 0;
int yStart = 15;
int oldAntialias = e.gc.getAntialias();
e.gc.setAntialias(SWT.ON);
// Line
e.gc.drawLine(xStart, yStart, xStart + w, yStart);
// Arrow left
e.gc.drawLine(xStart, yStart - 5, xStart, yStart + 5);
e.gc.drawLine(xStart, yStart, xStart + 8, yStart + 4);
e.gc.drawLine(xStart, yStart, xStart + 8, yStart - 4);
// Arrow right
e.gc.drawLine(xStart + w, yStart - 5, xStart + w, yStart + 5);
e.gc.drawLine(xStart + w, yStart, xStart + w - 8, yStart + 4);
e.gc.drawLine(xStart + w, yStart, xStart + w - 8, yStart - 4);
// text: 123 px
e.gc.setFont(Display.getDefault().getSystemFont());
String text = " " + w + " px ";
e.gc.drawString(text, xStart + w / 2 - e.gc.stringExtent(text).x / 2, 8);
e.gc.setAntialias(oldAntialias);
}
};
}
private PaintListener createVerticalRulerPainter() {
return new PaintListener() {
public void paintControl(PaintEvent e) {
int h = innerComposite.getBounds().height;
if (h == 0) {
return;
}
int xStart = 15;
int yStart = 0;
int oldAntialias = e.gc.getAntialias();
e.gc.setAntialias(SWT.ON);
// Line
e.gc.drawLine(xStart, yStart, xStart, yStart + h - 1);
// Arrow up
e.gc.drawLine(xStart - 5, yStart, xStart + 5, yStart);
e.gc.drawLine(xStart, yStart, xStart + 4, yStart + 8);
e.gc.drawLine(xStart, yStart, xStart - 4, yStart + 8);
// Arrow down
e.gc.drawLine(xStart - 5, yStart + h - 1, xStart + 5, yStart + h - 1);
e.gc.drawLine(xStart, yStart + h - 1, xStart + 4, yStart + h - 9);
e.gc.drawLine(xStart, yStart + h - 1, xStart - 4, yStart + h - 9);
// text: 123 px
String text = " " + h + " px ";
e.gc.setFont(Display.getDefault().getSystemFont());
Transform transform = new Transform(e.gc.getDevice());
transform.translate(7, yStart + (h / 2) + e.gc.stringExtent(text).x / 2);
transform.rotate(-90);
e.gc.setTransform(transform);
e.gc.drawText(text, 0, 0);
e.gc.setTransform(null);
transform.dispose();
e.gc.setAntialias(oldAntialias);
}
};
}
public Composite getResizeableComposite() {
return innerComposite;
}
}