Refining the Shape Drawing
Go Up to Creating a graphic component Index
The standard shape control does one more thing that your sample shape control does not yet do: it handles squares and circles as well as rectangles and ellipses. To do that, you need to write code that finds the shortest side and centers the image.
Here is a refined Paint method that adjusts for squares and ellipses:
procedure TSampleShape.Paint;
var
X, Y, W, H, S: Integer;
begin with Canvas do
begin
Pen := FPen; { copy the component's pen }
Brush := FBrush; { copy the component's brush }
W := Width; { use the component width }
H := Height; { use the component height }
if W < H then S := W else S := H; { save smallest for circles/squares }
case FShape of { adjust height, width and position }
sstRectangle, sstRoundRect, sstEllipse:
begin
X := 0; { origin is top-left for these shapes }
Y := 0;
end;
sstSquare, sstRoundSquare, sstCircle:
begin
X := (W - S) div 2; { center these horizontally... }
Y := (H - S) div 2; { ...and vertically }
W := S; { use shortest dimension for width... }
H := S; { ...and for height }
end;
end;
case FShape of
sstRectangle, sstSquare:
Rectangle(X, Y, X + W, Y + H); { draw rectangles and squares }
sstRoundRect, sstRoundSquare:
RoundRect(X, Y, X + W, Y + H, S div 4, S div 4); { draw rounded shapes }
sstCircle, sstEllipse:
Ellipse(X, Y, X + W, Y + H); { draw round shapes }
end;
end;
end;
void __fastcall TSampleShape::Paint(void)
{
int X,Y,W,H,S;
Canvas->Pen = FPen; // copy the component's pen
Canvas->Brush = FBrush; // copy the component's brush
W=Width; // use the component width
H=Height; // use the component height
X=Y=0; // save smallest for circles/squares
if( W<H )
S=W;
else
S=H;
switch(FShape) // adjust height, width and position
{
case sstRectangle:
case sstRoundRect:
case sstEllipse:
Y=X=0; // origin is top-left for these shapes
break;
case sstSquare:
case sstRoundSquare:
case sstCircle:
X= (W-S)/2; // center these horizontally
Y= (H-S)/2; // and vertically
break;
default:
break;
}
switch(FShape)
{
case sstSquare: // draw rectangles and squares
W=H=S; // use shortest dimension for width and height
case sstRectangle:
Canvas->Rectangle(X,Y,X+W,Y+H);
break;
case sstRoundSquare: // draw rounded rectangles and squares
W=H=S;
case sstRoundRect:
Canvas->RoundRect(X,Y,X+W,Y+H,S/4,S/4);
break;
case sstCircle: // draw circles and ellipses
W=H=S;
case sstEllipse:
Canvas->Ellipse(X,Y,X+W,Y+H);
break;
default:
break;
}
}