Drawing Shapes (Code)

From RAD Studio
Jump to: navigation, search

Go Up to Using Drawing Tools


Drawing shapes is just as easy as drawing lines. Each one takes a single statement; you just need the coordinates.

Here's a rewrite of the OnMouseUp event handler that draws shapes for all four tools:

procedure TForm1.FormMouseUp(Sender: TObject; Button TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  case DrawingTool of
    dtLine:
      begin
        Canvas.MoveTo(Origin.X, Origin.Y);
        Canvas.LineTo(X, Y)
      end;
    dtRectangle:
      Canvas.Rectangle(Origin.X, Origin.Y, X, Y);
    dtEllipse:
      Canvas.Ellipse(Origin.X, Origin.Y, X, Y);
    dtRoundRect:
      Canvas.RoundRect(Origin.X, Origin.Y, X, Y, (Origin.X - X) div 2,
        (Origin.Y - Y) div 2);
  end;
  Drawing := False;
end;
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
	TShiftState Shift, int X, int Y) {
	switch (DrawingTool) {

	case dtLine:
		Canvas->MoveTo(Origin.x, Origin.y);
		Canvas->LineTo(X, Y);
		break;

	case dtRectangle:
		Canvas->Rectangle(Origin.x, Origin.y, X, Y);
		break;

	case dtEllipse:
		Canvas->Ellipse(Origin.x, Origin.y, X, Y);
		break;

	case dtRoundRect:
		Canvas->Rectangle(Origin.x, Origin.y, X, Y, (Origin.x - X) / 2,
			(Origin.y - Y) / 2);

		break;
	}
	Drawing = false;
}

Of course, you also need to update the OnMouseMove handler to draw shapes:

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  if Drawing then
  begin
    Canvas.Pen.Mode := pmNotXor;
    case DrawingTool of
      dtLine:
        begin
          Canvas.MoveTo(Origin.X, Origin.Y);
          Canvas.LineTo(MovePt.X, MovePt.Y);
          Canvas.MoveTo(Origin.X, Origin.Y);
          Canvas.LineTo(X, Y);
        end;
      dtRectangle:
        begin
          Canvas.Rectangle(Origin.X, Origin.Y, MovePt.X, MovePt.Y);
          Canvas.Rectangle(Origin.X, Origin.Y, X, Y);
        end;
      dtEllipse:
        begin
          Canvas.Ellipse(Origin.X, Origin.Y, X, Y);
          Canvas.Ellipse(Origin.X, Origin.Y, X, Y);
        end;
      dtRoundRect:
        begin
          Canvas.RoundRect(Origin.X, Origin.Y, X, Y, (Origin.X - X) div 2,
            (Origin.Y - Y) div 2);
          Canvas.RoundRect(Origin.X, Origin.Y, X, Y, (Origin.X - X) div 2,
            (Origin.Y - Y) div 2);
        end;
    end;
    MovePt := Point(X, Y);
  end;
  Canvas.Pen.Mode := pmCopy;
end;
vvoid __fastcall TForm1::FormMouseMove(TObject *Sender, TMouseButton Button,
	TShiftState Shift, int X, int Y) {
	if (Drawing) {
		Canvas->Pen->Mode = pmNotXor; // use XOR mode to draw/erase
		switch (DrawingTool) {
		case dtLine:
			Canvas->MoveTo(Origin.x, Origin.y);
			Canvas->LineTo(MovePt.x, MovePt.y);
			Canvas->MoveTo(Origin.x, Origin.y);
			Canvas->LineTo(X, Y);
			break;
		case dtRectangle:
			Canvas->Rectangle(Origin.x, Origin.y, MovePt.x, MovePt.y);
			Canvas->Rectangle(Origin.x, Origin.y, X, Y);
			break;
		case dtEllipse:
			Canvas->Ellipse(Origin.x, Origin.y, MovePt.x, MovePt.y);
			Canvas->Ellipse(Origin.x, Origin.y, X, Y);
			break;
		case dtRoundRect:
			Canvas->Rectangle(Origin.x, Origin.y, MovePt.x, MovePt.y,
				(Origin.x - MovePt.x) / 2, (Origin.y - MovePt.y) / 2);
			Canvas->Rectangle(Origin.x, Origin.y, X, Y, (Origin.x - X) / 2,
				(Origin.y - Y) / 2);
			break;
		}
		MovePt = Point(X, Y);
	}
	Canvas->Pen->Mode = pmCopy;
}

Typically, all the repetitious code that is in the above example would be in a separate routine. The next topic shows all the shape-drawing code in a single routine that all mouse-event handlers can call.

See Also