Apart from the top-most layer (TLayeredImage32.Root), all layers are nested within other layers. Nested layers are usually confined to the clipping region of their Parent layer, unless that Parent happens to be a TGroupLayer32 object. TGroupLayer32 objects are intended to group related child layers (to simplify their construction and destruction) without confining them to a specific region. Grouping layers also improves rendering performance since they can be blended collectively rather than as individual layers.
TLayeredImage32.Root) is a TGroupLayer32 that's created automatically when its owner TLayeredImage32 is created.
The Img32.Layers unit also defines several descendants of TGroupLayer32 - TSizingGroupLayer32, TRotatingGroupLayer32 and TButtonGroupLayer32.
Note: Since TGroupLayer32 is a TLayer32 descendant, it has an Image property. However, this Image is used internally and should not be drawn on directly.
var
clickedPoint : TPoint;
clickedLayer : TLayer32;
targetLayer : TLayer32;
sizingbuttongroup : TSizingGroupLayer32;
procedure TForm1.FormMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
clickedPoint := Types.Point(X,Y);
clickedLayer := layeredImage.GetLayerAt(clickedPoint);
if not Assigned(clickedLayer) then
begin
//destroy any existing sizing buttons
FreeAndNil(sizingbuttongroup);
targetLayer := nil;
end
//else if clicking on a new target ...
else if not (clickedLayer is TDesignerLayer32) and
(clickedLayer <> targetLayer) then
begin
//destroy any existing sizing buttons
FreeAndNil(sizingbuttongroup);
//assigned target
targetLayer := clickedLayer;
//create a new group of sizing buttons
sizingbuttongroup :=
CreateSizingButtonGroup(targetLayer,
ssCorners, bsRound, DefaultButtonSize, clRed32);
end;
//The surface where layeredImage is being
//displayed will need refreshing
Invalidate;
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 = targetLayer) then
//also move all the sizing buttons
sizingbuttongroupbuttongroup.Offset(dx, dy)
else
begin
//respond to a sizing button move ...
//UpdateSizingButtonGroup auto-adjusts other
//button positions and returns the new BoundsRect
rec := UpdateSizingButtonGroup(clickedLayer);
targetLayerLayer.SetBounds(rec);
//and targetLayer may also need redrawing
end;
//The surface where layeredImage is being
//displayed will need refreshing
Invalidate;
end;
procedure TForm1.FormMouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
clickedLayer := nil;
end;
TButtonGroupLayer32, TLayer32, TLayeredImage32.Root, TRotatingGroupLayer32, TSizingGroupLayer32
Copyright ©2010-2023 Angus Johnson - Image32 4.8 - Help file built on 16 Apr 2025