2

我正在开发一个新的 Eclipse 插件,使用 GEF(Draw2d 3.9,Zest 1.5.0)和自定义数字来表示一些数据。我现在正在尝试开发可调节的镜头视图。所需的功能是将鼠标拖动到主窗口上,“镜头视图窗口”将代表所选区域。

为此,我使用带有 SWT 画布的窗口作为镜头视图。主窗口的(图形)内容绘制在镜头画布上。然后我将镜头画布的另一个区域(可能在可见区域之外)复制到点 0,0(镜头画布的)。问题是镜头画布忽略了在其可见区域之外绘制的所有内容,当我复制上述区域时,我得到黑色而不是内容。

将图表的内容复制到图像,然后绘制图像的一部分不是解决方案,因为我的图表可能很大(> 200000 x 200000)。

您可以在下面找到我的代码的一部分:

import org.eclipse.draw2d.SWTGraphics;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.zest.core.widgets.Graph;

public class LensView {
private final Shell shell;
private final Canvas canvas;

private final Point focalPoint;
private float lensScaleFactor;
private float mainScaleFactor;

public LensView(final Graph graph, Display d) {
    this.visualizer = visualizer;
    focalPoint = new Point(0, 0);

    lensScaleFactor     = 1.0f;
    mainScaleFactor = 1.0f;

    shell = new Shell(d, SWT.SHELL_TRIM);
    shell.setSize(640, 480);
    shell.setLayout(new FillLayout());  
    canvas = new Canvas(shell, SWT.NO_REDRAW_RESIZE);
    canvas.setLayout(new FillLayout());

    canvas.addPaintListener(new PaintListener() {   
        @Override
        public void paintControl(PaintEvent e) {
            Rectangle area  = canvas.getClientArea();
            //Scale the origin to 1.0 and apply our scale factor
            float scale = lensScaleFactor/mainScaleFactor; 

            Point viewLocation = graph.getViewport().getViewLocation();
            int tmpx = normaliseDec(Math.round((focalPoint.x + viewLocation.x) * scale) - Math.round(area.width/2.0f));
            int tmpy = normaliseDec(Math.round((focalPoint.y + viewLocation.y) * scale) - Math.round(area.height/2.0f));

            GC gc = new GC(canvas);
            SWTGraphics graphics = new SWTGraphics(gc);
            graphics.scale(scale);  
            graph.getContents().paint(graphics);                

            e.gc.copyArea(tmpx, tmpy, area.width, area.height, 0, 0);

            graphics.dispose();
            gc.dispose();
        }
    });
}

public void redraw (int x, int y) {
    focalPoint.x = normaliseDec(x);
    focalPoint.y = normaliseDec(y);
    canvas.redraw();
    canvas.update();
}

private int normaliseDec (int i) {
    return i < 0 ? 0 : i;
}

}
4

1 回答 1

0

想想您需要做的就是从 PaintEvent 附带的 GC 创建 ScaledGraphics 对象,设置图形的缩放因子,设置剪切矩形,然后绘制图形。类似的东西(没有测试它,大致是这样的):

ScaledGraphics graphics = new ScaledGraphics(e.gc);
graphics.scale(scale);
graphics.setClip(new Rectangle(focalPoint, getClientArea().getSize()));
graph.getContents().paint(graphics);
graphics.dispose();

几点: - ScaledGraphics 应该为你做裁剪矩形的缩放 - 应该在控件 GC 上绘制而不是创建一个新的

于 2014-07-05T01:51:48.923 回答