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); } } }