package logbook.gui;
import logbook.gui.logic.ColorManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.wb.swt.SWTResourceManager;
/**
* 矩形選択ウインドウ
*
*/
public final class FullScreenDialog extends Dialog {
private Shell shell;
private ScreenCanvas canvas;
private final Image image;
private final Display monitor;
/**
* Create the dialog.
*
* @param parent
* @param image 矩形選択の背景画像
*/
public FullScreenDialog(Shell parent, Image image, Display monitor) {
super(parent, SWT.NO_TRIM);
this.setText("矩形選択");
this.image = image;
this.monitor = monitor;
}
/**
* Open the dialog.
*
* @return 選択された領域
*/
public Rectangle open() {
this.createContents();
try {
this.shell.open();
this.shell.layout();
Display display = this.getParent().getDisplay();
while (!this.shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} finally {
this.canvas.dispose();
}
return this.canvas.getAbsoluteRectangle();
}
/**
* Create contents of the dialog.
*/
private void createContents() {
// フルスクリーンのウインドウを作成します
this.shell = new Shell(this.getParent(), this.getStyle());
this.shell.setText(this.getText());
this.shell.setBounds(this.monitor.getBounds());
this.shell.setFullScreen(true);
GridLayout glShell = new GridLayout(1, false);
glShell.verticalSpacing = 0;
glShell.marginWidth = 0;
glShell.horizontalSpacing = 0;
glShell.marginHeight = 0;
this.shell.setLayout(glShell);
// ウインドウいっぱいにキャプチャした画像を貼り付けます
this.canvas = new ScreenCanvas(this.shell, this.image, this.monitor);
this.canvas.setLayoutData(new GridData(GridData.FILL_BOTH));
this.canvas.addPaintListener(this.canvas);
this.canvas.addMouseListener(this.canvas);
this.canvas.addMouseMoveListener(this.canvas);
this.canvas.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_CROSS));
this.shell.setActive();
}
/**
* 矩形選択のためのキャンバスクラス
*
*/
private static final class ScreenCanvas extends Canvas implements PaintListener, MouseListener, MouseMoveListener {
private final Image image;
private final Display monitor;
private final Color white = ColorManager.getColor(new RGB(255, 255, 255));
private final Color black = ColorManager.getColor(new RGB(0, 0, 0));
private final Font normalfont;
private final Font largefont;
private int x1;
private int y1;
private int x2;
private int y2;
public ScreenCanvas(Shell shell, Image image, Display monitor) {
super(shell, SWT.NO_BACKGROUND);
this.image = image;
this.monitor = monitor;
// 描画に使用するフォントを設定します
FontData normal = shell.getFont().getFontData()[0];
FontData large = new FontData(normal.getName(), 18, normal.getStyle());
this.normalfont = new Font(Display.getDefault(), normal);
this.largefont = new Font(Display.getDefault(), large);
}
@Override
public void paintControl(PaintEvent e) {
Rectangle m = this.monitor.getBounds();
GC gc = e.gc;
gc.drawImage(this.image, 0, 0, m.width, m.height, 0, 0, m.width, m.height);
gc.setFont(this.largefont);
gc.setForeground(this.black);
gc.setBackground(this.white);
gc.drawString("キャプチャする領域をマウスでドラッグして下さい。 [Esc]キーでキャンセル", -m.x + 2, -m.y + 2);
}
@Override
public void mouseMove(MouseEvent e) {
if ((e.stateMask & SWT.BUTTON1) != 0) {
GC gc = new GC(this);
gc.setXORMode(true);
gc.setForeground(this.white);
gc.drawRectangle(this.getRectangle());
this.x2 = e.x;
this.y2 = e.y;
gc.drawRectangle(this.getRectangle());
gc.setXORMode(false);
gc.setFont(this.normalfont);
gc.setForeground(this.black);
gc.setBackground(this.white);
String msg = "(" + this.x1 + "," + this.y1 + ")-(" + this.x2 + "," + this.y2 + ")";
gc.drawString(msg, this.x1, this.y1);
gc.dispose();
}
}
@Override
public void mouseDoubleClick(MouseEvent e) {
}
@Override
public void mouseDown(MouseEvent e) {
if (e.button == 1) {
this.x1 = this.x2 = e.x;
this.y1 = this.y2 = e.y;
this.setCapture(true);
}
}
@Override
public void mouseUp(MouseEvent e) {
if (e.button == 1) {
this.x2 = e.x;
this.y2 = e.y;
this.setCapture(false);
Rectangle rectangle = this.getRectangle();
// 範囲が十分ある場合
if ((rectangle.width > 2) && (rectangle.height > 2)) {
MessageBox msg = new MessageBox(this.getShell(), SWT.YES | SWT.NO | SWT.ICON_QUESTION);
msg.setText("矩形選択");
msg.setMessage("この範囲でよろしいですか?");
if (msg.open() == SWT.YES) {
this.getShell().close();
return;
}
}
this.redraw();
}
}
@Override
public void dispose() {
this.normalfont.dispose();
this.largefont.dispose();
super.dispose();
}
public Rectangle getRectangle() {
return new Rectangle(Math.min(this.x1, this.x2), Math.min(this.y1, this.y2), Math.abs(this.x2 - this.x1),
Math.abs(this.y2 - this.y1));
}
public Rectangle getAbsoluteRectangle() {
Rectangle m = this.monitor.getBounds();
Rectangle r = this.getRectangle();
return new Rectangle(r.x + m.x, r.y + m.y, r.width, r.height);
}
}
}