Рисуя слой Я имею в виду слой, в котором пользователь может рисовать линии, круги или другие фигуры вручную. И по нормальным слоям я имею в виду слои, описанные в примере с примерами graphics32 (слои, которые можно перемещать или изменять размер во время выполнения с использованием событий мыши) Поэтому у меня возникают трудности с объединением этих двух типов слоев. В моем тестовом проекте на данный момент я предполагаю, что у меня есть только один слой рисования и несколько слоев PNG. Так что в моем проекте я установить свойства для ImgView32 в OnFormCreate как:Delphi Graphics32, объединяющий нормальные слои с рисовыми слоями
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 является только подвижным и изменяемым по размеру, поэтому это нехорошее решение, так как я хочу использовать мои события Mouse в этом конкретном слое для рисования. Если я комментирую только
RBLayer:=nil
, сохраняя при этомSelection:=BB
то drawingLayer не движимое больше, но я не могу выбрать другие слои, которые под drawingLayer. Я могу получить доступ только к верхнему слою (последний добавленный слой PNG)Если я прокомментирую
Selection:=BB
, тогда я не могу выбрать другие слои с помощью мыши. Поэтому в моем случае я объявил 2 слоя png перед моим drawLayer и один после него. Во время выполнения я могу выбрать только последний слой (тот, что «выше», слой рисования) Так что это тоже не решение.
Как я могу это сделать, что, когда я нажимаю на чертежной слой (или выберите его иначе, как в ListBox или что-то), то drawingLayer обыкновение быть подвижным, но мой рисунок событий мыши будет удар в? И все это, пока я могу уйти от DrawLayer всякий раз, когда захочу, и выбирать другие слои для перемещения и игры. Так что в основном мне нужен определенный слой, чтобы НЕ действовать как другие слои.
То, что я хочу достичь, - это классическое использование Photoshop-like или paint.net, использующее графику32. И это очень запутывает, как эти свойства слоя действительно работают.
До сих пор я выяснял, как рисовать (линии, круги, прямоугольники) на прозрачном слое динамически (используя события мыши). Поэтому у меня может быть слой рисования. Рисунок происходит в моих DrLayerMouseDown
, DrLayerMouseUp
, DrLayerMouseMove
, DrLayerPaint
событий. Но я не могу понять, как объединить такой слой рисования с обычными подвижными/изменяемыми размерами слоями.
Остальная часть кода (например, setSelection
, RBResizing
и layerMouseDown
) в основном взята из примера примеров библиотеки graphics32.
EDIT
Для того, чтобы проверить свою идею с layerOptions
, я сделал следующее:
1.Started новый тестовый проект с ImgView на нем, и кнопка
2 .On create Я использовал тот же код, что и раньше
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;
...
Ожидая, что он станет нечувствительным к событиям мыши. Но слой по-прежнему перемещается, а не нечувствителен к мыши. Так что я ничего не делал
Так что я не думаю, что это помогает мне использовать эту опцию, если я не ошибаюсь Так что настроить слой, этот параметр, похоже, не застрял. Но если отключить события мыши для всех слоев, один за другим, как в следующем EDIT, то рисунок слой получает отключается (события мыши)
EDIT
Также я попробовал другой тестовый проект, то же самое idea: same 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, мне нужно отключить события мыши для всех слоев и включить события мыши для определенного уровня, а затем, когда будет выполнено редактирование, мне нужно будет снова активировать мышь события для всех слоев, но я делаю это неправильно, я думаю.
Кажется, я прокомментировал не то место, под моим ответом, извините. Во всяком случае, в ответ на ваши изменения относительно включения событий мыши снова. Чтобы включить использование оператора OR, например, в LayerOptions: = LayerOptions или LOB_MOUSE_EVENTS. Изображения исчезли, потому что при использовании оператора AND вы очистили бит LOB_VISIBLE. Вы должны прочитать о логических операциях и битовых полях. –
Хорошие новости: Graphics32 был обновлен в прошлом месяце (04.2017) – Ampere