通过绘制图层,我指的是用户可以手动绘制线条、圆圈或其他形状的图层。对于普通层,我指的是graphics32层示例中描述的层(可以在运行时使用鼠标事件移动或调整大小的层),所以我很难组合这两种类型的层。在我的测试项目中,现在我假设我只有一个绘图层和多个PNG层。因此,在我的项目中,我在ImgView32中为OnFormCreate设置了属性,如:
procedure TForm1.FormCreate(Sender: TObject);
begin
AWidth:= 800;
AHeight:= 600;
FillColor:=clWhite;
with ImgView do
begin
Selection := nil;
RBLayer := nil;
Layers.Clear;
Scale := 1;
Scaled:=true;
Bitmap.SetSize(AWidth, AHeight);
Bitmap.DrawMode := dmTransparent;
Bitmap.Clear(FillColor);
end;
end;
在此之后,onClick的一个按钮,我添加了许多层(包含透明的PNG图像)。所以就像这样
procedure TForm1.Button1Click(Sender: TObject);
begin
AddPNGLayer(1);
AddPNGLayer(2);
AddDrawingLayer;
AddPNGLayer(3);
end;
(为了使问题简短,我不想在这里详细说明添加PNG层。我只想说,它使用的onMouseDown事件(layerMouseDown)与drawingLayer中使用的事件不同,AddDrawingLayer如下所示:
procedure TForm1.AddDrawingLayer;
var
P:TPoint;
jumaH, JumaW, W, H: Single;
begin
imwidth := ImgView.Bitmap.Width;
imheight := ImgView.Bitmap.Height;
xofx := (ImgView.ClientWidth - 17 - imwidth) div 2; // substracting the width of the scrollbar
yofy := (ImgView.ClientHeight - 17 - imheight) div 2; // same here with height
bm32 := TBitmap32.Create;
bm32.DrawMode := dmTransparent;
bm32.SetSize(ImgView.Bitmap.Width,ImgView.Bitmap.Height);
bm32.Canvas.Pen.Width := 3;
bm32.Canvas.Pen.Color := clBlack32;//pencolor;
BB := TBitmapLayer.Create(ImgView.Layers);
try
BB.Bitmap.DrawMode := dmTransparent;
BB.Bitmap.SetSize(imwidth,imheight);
BB.Bitmap.Canvas.Pen.Width := 3;
BB.Bitmap.Canvas.Pen.Color := pencolor;
BB.Location := GR32.FloatRect(0, 0, imwidth, imheight);
BB.Scaled := true;
BB.Tag:=3;
//// Selection:=BB; // if I use this then I cant draw because the entire layer is selected and the mouseDown event works as a mover/resizer
// BB.OnMouseDown := DrLayerMouseDown;
// BB.OnMouseUp := DrLayerMouseUp;
// BB.OnMouseMove := DrLayerMouseMove;
// BB.OnPaint := DrLayerOnPaint;
RBLayer:=nil;
EdLayerIndex.Text:=IntToStr(BB.Index);
finally
BB.Free;
end;
FDrawingLine := false;
// swapBuffers32; // needed when mouse events are active
end;
EdLayerIndex是一个EditBox,我在其中显示创建/选择的层索引(用于调试)。
Selection:=BB
和RBLayer:=nil
,那么drawingLayer只能是可移动的和可调整大小的,所以这不是一个好的解决方案,因为我想使用这个特定层中的鼠标事件来绘制。RBLayer:=nil
而保留Selection:=BB
,那么drawingLayer就不再是可移动的了,但是我不能选择drawingLayer下的其他层。我只能访问顶层(最后一次添加PNG层)。Selection:=BB
,那么我就不能用鼠标选择其他层。因此,在我的例子中,我在drawingLayer之前声明了两个png层,在它之后声明了一个。在运行时,我只能选择最后一个层(“高于”drawingLayer),因此这也不是一个解决方案。当我单击绘图层(或者在列表框或其他地方选择它)时,drawingLayer将无法移动,但我的绘图鼠标事件会启动?所有这一切,我可以离开drawingLayer,随时我想,并选择其他层移动和播放。所以基本上,我需要一个特殊的图层,而不是其他的层。
我想实现的是拥有一个典型的类似Photoshop或类似paint.net的行为使用graphics32。这些层的属性是如何工作的,这是非常令人困惑的。
到目前为止,我已经知道了如何动态地(使用鼠标事件)在透明层上绘制(线条、圆圈、矩形)。这样我就可以画一个图层了。这幅画发生在我的DrLayerMouseDown
,DrLayerMouseUp
,DrLayerMouseMove
,DrLayerPaint
事件中。但我似乎不明白如何将这样的绘图层与可移动/可调整大小的规则层相结合。
其余的代码(如setSelection
、RBResizing
和layerMouseDown
)主要是从graphics32库的层示例中获取的。
编辑
为了用layerOptions
测试您的想法,我做了以下工作:
1.启动一个新的测试项目,上面有一个ImgView,还有一个按钮
2.在创建时,我使用了与前面相同的代码
3.OnButtonClick使用修改后的AddDrawingLayer添加了一个层,如下所示:
...
BB.Scaled := true;
Selection:=BB;
Selection.LayerOptions:=Selection.LayerOptions and (not LOB_MOUSE_EVENTS); // I also tried it with BB instead of Selection
BB.OnMouseDown := DrLayerMouseDown;
BB.OnMouseUp := DrLayerMouseUp;
BB.OnMouseMove := DrLayerMouseMove;
BB.OnPaint := DrLayerOnPaint;
...
希望它对鼠标事件变得不敏感。但这一层仍然是可移动的,而不是对鼠标不敏感。所以我好像什么都没做
因此,我不认为它帮助我使用这个选项,除非我做错了,所以层的onCreate,这个选项似乎不坚持。但是,如果我禁用了所有层的鼠标事件,像在下一个编辑中一个一个地禁用鼠标事件,那么绘图层将被禁用(鼠标事件)。
编辑
我还尝试了另一个测试项目,相同的想法:相同的onCreate和onButtonClick --我添加了3个层(使用库的图层示例),每个层都包含一个图像(这次没有绘图层,以保持简单)。然后,我添加了一个新按钮,如果单击它,将执行下一段代码:
for i := 0 to ImgView.Layers.Count-1 do
(ImgView.Layers.Items[i] as TPositionedLayer).LayerOptions:= (ImgView.Layers.Items[i] as TPositionedLayer).LayerOptions and (not LOB_MOUSE_EVENTS);
我的目的是让所有层都对鼠标事件不敏感。我成功了,在单击新按钮后,无法再选择这些层,但是,当我希望为这些层重新启用鼠标事件时(添加第三个带有下一个代码onClick的按钮):
for i := 0 to ImgView.Layers.Count-1 do
(ImgView.Layers.Items[i] as TPositionedLayer).LayerOptions:= (ImgView.Layers.Items[i] as TPositionedLayer).LayerOptions and (LOB_MOUSE_EVENTS);
没有显示错误,但是当我试图选择一个图层来移动它时.所有的图层图像都从视野中消失了.给我留下一个白色背景空ImgView。
我做错了什么?为了执行您对LayerOptions的建议,我需要能够禁用所有层的鼠标事件,并为特定层启用鼠标事件,然后当编辑完成时,我需要能够为所有层重新启用鼠标事件,但我想我做错了。
发布于 2015-02-22 13:15:46
下列项目影响鼠标事件
基于之前的建议,当用户进入“编辑”模式时,通过将其LayerOptions设置为不包括LOB_MOUSE_EVENTS位,可以禁用除绘图层之外的所有其他层。
Layer.LayerOptions := Layer.LayerOptions and (not LOB_MOUSE_EVENTS);
有关使用层的更多信息,请参阅这里。
编辑
要管理LOB_MOUSE_EVENTS创建,例如,如下所示
procedure TForm7.LayerMouseDisEnable(Enable: boolean);
var
i: integer;
Lo: cardinal;
begin
for i := 0 to ImgView.Layers.Count-1 do
begin
Lo := ImgView.Layers.Items[i].LayerOptions;
if Enable then
ImgView.Layers.Items[i].LayerOptions := Lo or LOB_MOUSE_EVENTS
else
ImgView.Layers.Items[i].LayerOptions := Lo and (not LOB_MOUSE_EVENTS);
end;
end;
在创建绘图层之前调用它(使用False)来禁用图层中的鼠标事件。绘图层将启用鼠标事件,因为新创建的层同时设置了LOB_VISIBLE和LOB_MOUSE_EVENTS。停止绘图以启用鼠标事件时再次调用(使用True)。
https://stackoverflow.com/questions/28623999
复制相似问题