Refining the Shape Drawing

From RAD Studio
Jump to: navigation, search

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;
  }
}