Domanda

I need a clickable control that I can tailor to my needs. From the Delphi docs I gathered that a TRectangle would do. I need to create my TRectangles programmatically, so I created a Form, a Panel and a Button (see code below). As TRectangle is derived via TShape from TControl I tested whether I could draw on the TRectangle Canvas using PaintTo, using its own canvas. The TRectF I constructed was created on the assumption that the painting would be relative to the TRectangle's Canvas, so an offset of (0, 0) was needed. The rectangle however is painted at position (0, 0) of the Form! Without paying heed to the changes in the Fill and Stroke properties I made.

I next tried a FillRect and again the same results, although with the correct Fill. Though the call is from a Trectangle variable.Canvas.FillRect, It is always relative to the highest parent in the tree, bypassing TRectangle and TPanel. I always thought that painting is relative to the coordinates of the TControl a Canvas is part of.

Is this wrong or is there something special with TRectangle? Is there a better way of painting on a TRectangle?

unit rect_test_main;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Objects;

type
   TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;

    procedure Button1Click (Sender: TObject);
    procedure FormCreate (Sender: TObject);

   protected
      FR: TRectangle;

   public
      procedure draw_paintto (rect: TRectangle);
      procedure draw_rect (rect: TRectangle);
      procedure draw_fill (rect: TRectangle);
      procedure draw (surface: TControl);
   end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormCreate (Sender: TObject);
begin
   FR := Trectangle.Create (Panel1);
   FR.Parent := Panel1;
   FR.Canvas.BeginScene;
   FR.Canvas.Fill.Color := TAlphaColors.Black;
   FR.Canvas.Stroke.Color := TAlphaColors.Green;
   FR.SetBounds (200, 200, 50, 300);
   FR.OnClick := Button1Click;
   FR.Canvas.EndScene;
end; // FormCreate //

procedure TForm1.Button1Click (Sender: TObject);
begin
   draw_fill (FR);
end;

procedure TForm1.draw_paintto (rect: TRectangle);
var
   r: TRectF;
begin
   FR.Canvas.BeginScene;
   FR.Canvas.Fill.Color := TAlphaColors.Black;
   FR.Canvas.Stroke.Color := TAlphaColors.Green;
   FR.Canvas.Stroke.Thickness := 10;
   r := rect.ShapeRect;
//   r := TRectF.Create (TPointF.Create (FR.Position.X - 10, FR.Position.Y - 10), FR.Width, FR.Height);
   FR.PaintTo (FR.Canvas, r, FR.Parent);
   FR.Canvas.EndScene;
end; // draw_paintto //

procedure TForm1.draw_fill (rect: TRectangle);
var
   r: TRectF;
begin
   FR.Canvas.BeginScene;
   FR.Canvas.Fill.Color := TAlphaColors.Black;
   FR.Canvas.Stroke.Color := TAlphaColors.Green;
   FR.Canvas.Stroke.Thickness := 10;
   r := TRectF.Create (TPointF.Create (FR.Position.X, FR.Position.Y), FR.Width, FR.Height);
   FR.Canvas.FillRect (r, 0, 0, AllCorners, 1);
   FR.Canvas.EndScene;
end; // draw_fill //
È stato utile?

Soluzione

When drawing on a TRectangle one should access the brush and stroke changes on the TRectangle level and not on the Canvas. In this case all works as expected, the Canvas of the TRectangle is drawn.

Key: TRectangle;
...
Key.Fill.Color := TAlphaColors.White;
Key.Fill.Kind := TBrushKind.bkSolid; // and not Key.Canvas.Fill ...
Key.Stroke.Thickness := 1;
Key.Stroke.Color := TAlphaColors.Darkgray;
Key.Paint;

Why the TRectangle paints on the canvas of its Parent.Parent (in this case) when drawing on its Canvas beats me. Maybe it has no Canvas itself and TRectangle.Canvas is just a reference to its Parent.Canvas?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top