Img32.Layers

This unit contains the TLayeredImage32 class that provides a relatively easy way to manage multiple images that will at some stage be merged into a single image.

Each TLayer32 in a TLayeredImage32 object represents a single image though layers can also contain other layers. Layers can be nested to any level. Child layers will be restricted to the bounds of their parent layers, except for childs of TGroupLayer32.

While layers can have any position in the 2D plane, only those portions of layers that are within the bounds of their owner TLayeredImage32 will be visible when all the images are merged (see TLayeredImage32.GetMergedImage)

There are four basic layer classes that derive from TLayer32:

  1. TVectorLayer32 to display vector images
  2. TRasterLayer32 to display raster images
  3. TGroupLayer32 to group layers together
  4. TDesignerLayer32, layers with special features to aid interactive image design.

All layers are contained in a nested tree structure under the very top group layer - TLayeredImage32.Root



Example

uses 
  ...
  Img32, Img32.Layers, Img32.Draw, 
  Img32.Vector, Img32.Extra;

type
  TForm1 = class(TForm)
	// Form's full declaration removed for brevity
  public
    layeredImage: TLayeredImage32;
    vectorLayer : TLayer32;
    buttongroup : TSizingGroupLayer32;
    clickedLayer: TLayer32;
    clickedPoint: TPoint;
    procedure UpdateEllipseLayer(vecLayer: TVectorLayer32);
  end;

implementation

procedure TForm1.FormCreate(Sender: TObject);
begin
  //create a TLayeredImage32 object
  layeredImage := TLayeredImage32.Create(ClientWidth, ClientHeight);

  //TDESIGNERLAYER32
  with layeredImage.AddLayer(TDesignerLayer32) do
  begin
    SetSize(layeredImage.Width, layeredImage.Height);
    HatchBackground(Image);
  end;

  //TVECTORLAYER32
  //add a simple vector layer and draw an ellipse
  vectorLayer := layeredImage.AddLayer(TVectorLayer32) ;
  with vectorLayer do
  begin
    SetBounds(Rect(120, 120, 320, 220));
    CursorId := crHandPoint;
    UpdateEllipseLayer(vectorLayer as TVectorLayer32);
  end;

  //TGROUPLAYER32
  //add a (designing) button group to size the vector layer
  sizingbuttongroup := CreateSizingButtonGroup(vectorLayer,
    ssCorners, bsRound, DefaultButtonSize, clRed32);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  layeredImage.Free;
end;

procedure TForm1.UpdateEllipseLayer(vecLayer: TVectorLayer32);
var
  rec: TRect;
  pp: TPathsD;
  margin: integer;
begin
  //draw an ellipse on vecLayer and update the
  //hit-test mask so the layer will respond to clicking
  with vecLayer do
  begin
    margin := 5;
    rec := Rect(0, 0, Width, Height);
    rec := Img32.Vector.InflateRect(rec, -margin, -margin);
    SetLength(pp, 1);
    pp[0] := Ellipse(rec);
    DrawPolygon(Image, pp, frEvenOdd, $4000FFFF);
    DrawLine(Image, pp, 5, $FF006666, esPolygon);
    UpdateHitTestMask(pp, frEvenOdd);
  end;
end;

procedure TForm1.FormMouseDown(Sender: TObject; 
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  clickedLayer := layeredImage.GetLayerAt(Types.Point(X,Y));
  clickedPoint := Types.Point(X,Y);
end;

procedure TForm1.FormMouseMove(Sender: TObject; 
  Shift: TShiftState; X,Y: Integer);
var
  layer: TLayer32;
  dx, dy: integer;
  rec: TRect;
begin
  if not (ssLeft in Shift) then
  begin
    layer := layeredImage.GetLayerAt(Types.Point(X,Y));
    if Assigned(layer) then
      Cursor := layer.CursorId else
      Cursor := crDefault;
  end;

  if not Assigned(clickedLayer) then Exit;
  dx := X - clickedPoint.X;
  dy := Y - clickedPoint.Y;
  clickedPoint := Types.Point(X,Y);

  clickedLayer.Offset(dx, dy);
  if clickedLayer = vectorLayer then
    buttongroup.Offset(dx, dy) //move the sizing buttons too
  else
  begin
    //update the sizing group with moved clickedLayer
    rec := Rect(UpdateSizingButtonGroup(clickedLayer));
    //and resize and repaint vectorLayer accordingly.
    vectorLayer.SetBounds(rec);
    UpdateEllipseLayer(vectorLayer as TVectorLayer32);
  end;

  Invalidate;
end;

procedure TForm1.FormMouseUp(Sender: TObject; 
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  clickedLayer := nil;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  with layeredImage.GetMergedImage do
    CopyToDc(Self.Canvas.Handle);
end;
    

Contents

Types
TArrayOfPointer TButtonDesignerLayer32Class TGroupType THitTestRec TLayer32Class TLayerHitTestEvent TSizingStyle

Classes
TButtonDesignerLayer32 TButtonGroupLayer32 TDesignerLayer32 TGroupLayer32 THitTestLayer32 TLayer32 TLayeredImage32 TRasterLayer32 TRotateLayer32 TRotatingGroupLayer32 TSizingGroupLayer32 TVectorLayer32

Routines
CreateButtonGroup CreateRotatingButtonGroup CreateSizingButtonGroup UpdateRotatingButtonGroup UpdateSizingButtonGroup

Variables
Img32.Layers

Constants
Img32.Layers

See Also

TDesignerLayer32, TGroupLayer32, TLayer32, TLayeredImage32, TLayeredImage32.AddLayer, TLayeredImage32.GetLayerAt, TLayeredImage32.GetMergedImage, TLayeredImage32.Root, TRasterLayer32, TVectorLayer32