描画レイヤーとは、ユーザーが線、円、またはその他の形状を手動で描画できるレイヤーを意味します。また、通常のレイヤーとは、graphics32 レイヤーの例で説明されているレイヤー (実行時にマウス イベントを使用して移動またはサイズ変更できるレイヤー) を意味するため、これら 2 種類のレイヤーを組み合わせることが困難です。私のテスト プロジェクトでは、今のところ、1 つの描画レイヤーと複数の PNG レイヤーしかないと仮定します。したがって、私のプロジェクトでは、OnFormCreate で ImgView32 のプロパティを次のように設定します。
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 レイヤーの追加について詳しく説明しません。drawingLayer で使用されているものとは異なる onMouseDown イベント (layerMouseDown) を使用しているとだけ言います) 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
while keepだけコメントするとSelection:=BB
、drawingLayer はもう移動できませんが、drawingLayer の下にある他のレイヤーを選択することはできません。一番上のレイヤー (最後に追加された PNG レイヤー) にしかアクセスできませんコメントする
Selection:=BB
と、マウスで他のレイヤーを選択できなくなります。したがって、私の場合、drawingLayer の前に 2 つの png レイヤーを宣言し、その後に 1 つ宣言しました。実行時に最後のレイヤー (drawingLayer の「上」) しか選択できないため、これも解決策ではありません。
描画レイヤーをクリックすると(またはリストボックスなどで選択すると)、drawingLayerは移動できませんが、描画マウスイベントが開始されますか?そして、必要なときにいつでも drawingLayer から離れて、他のレイヤーを選択して移動したり遊んだりすることができます。したがって、基本的に、他のレイヤーのように機能しない特定のレイヤーが必要です。
私が達成したいのは、graphics32 を使用して、古典的な Photoshop のような、または paint.net のような動作をすることです。そして、これらのレイヤー プロパティが実際にどのように機能するかは非常にわかりにくいものです。
これまでのところ、(マウスイベントを使用して)透明レイヤーに(線、円、長方形)を動的に描画する方法を理解しました。だから私は描画レイヤーを持つことができます。描画は、、、、イベントで行わDrLayerMouseDown
れます。しかし、そのような描画レイヤーを通常の可動/サイズ変更可能なレイヤーと組み合わせる方法を理解できないようです。DrLayerMouseUp
DrLayerMouseMove
DrLayerPaint
コードの残りの部分 ( 、setSelection
、RBResizing
などlayerMouseDown
) は、ほとんどが graphics32 ライブラリのレイヤーの例から取られています。
編集
でアイデアをテストするためにlayerOptions
、次のことを行いました。
1. ImgView とボタンを含む新しいテスト プロジェクトを開始します。
2.作成時に、以前と同じコードを使用しました
3.OnButtonClick 次のように、修正された AddDrawingLayer を使用して 1 つのレイヤーを追加しました。
...
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 では、このオプションは固執していないようです。しかし、次の編集のように、すべてのレイヤーのマウス イベントを 1 つずつ無効にすると、描画レイヤーが無効になります (マウス イベント)。
編集
また、同じアイデアの別のテスト プロジェクトを試してみました: 同じ 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で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 (LOB_MOUSE_EVENTS);
エラーは表示されませんでしたが、移動するためにレイヤーを選択しようとすると...レイヤーのすべての画像がビューから消えました...白い背景の空のImgViewが残りました。
私は何を間違っていますか?LayerOptionsで提案したことを行うには、すべてのレイヤーのマウスイベントを無効にし、特定のレイヤーのマウスイベントを有効にする必要があり、編集が完了したら、マウスイベントを再度有効にする必要がありますすべてのレイヤーに対してですが、間違っていると思います。