Reputation: 4538
I have a set of TImage instances layed out on a panel. The TImages represent icons (see attached screenshot). I would like to draw a red rectangle around a given TImage instance when the user selects it by clicking on it. Not sure how to proceed...
Edit: why am I not using a TToolbar? Reason 1: I don't like the default "look and feel" of the TToolbar and I want to have more control on it. Reason 2: This control is not really a TToolbar. It should rather be considered as a sort of "bookmark" element, which displays different text in the memo field depending on which "bookmark" is selected.
The accepted solution using Remy Lebeau's suggestion is shown below:
Upvotes: 2
Views: 6996
Reputation: 11
I would modify the proposals. there would be no problem with the objects on the form type the following :
TImage = class(ExtCtrls.TImage)
private
FShowRectangle: Boolean;
procedure SetShowRectangle(Value: Boolean);
protected
procedure Paint; override;
public
property ShowRectangle: Boolean read FShowRectangle write SetShowRectangle;
end;
Upvotes: 1
Reputation: 595971
I would suggest using a TPaintBox
instead of a TImage
. Load your image into an appropriate TGraphic
class (TBitmap
, TIcon
, TPNGImage
, etc) and then draw it onto the TPaintBox
in its OnPaint
event. That is all a TImage
really does (it holds a TGraphic
that is drawn onto its Canvas
when painted). You can then draw a red rectangle on top of the image when needed. For example:
procedure TMyForm.PaintBox1Click(Sender: TObject);
begin
PaintBox1.Tag := 1;
PaintBox1.Invalidate;
PaintBox2.Tag := 0;
PaintBox2.Invalidate;
end;
procedure TMyForm.PaintBox2Click(Sender: TObject);
begin
PaintBox1.Tag := 0;
PaintBox1.Invalidate;
PaintBox2.Tag := 1;
PaintBox2.Invalidate;
end;
procedure TMyForm.PaintBox1Paint(Sender: TObject);
begin
PaintBox1.Canvas.Draw(MyImage1, 0, 0);
if PaintBox1.Tag = 1 then
begin
PaintBox1.Canvas.Brush.Style := bsClear;
PaintBox1.Canvas.Pen.Color := clRed;
PaintBox1.Canvas.Rectangle(PaintBox1.ClientRect);
end;
end;
procedure TMyForm.PaintBox2Paint(Sender: TObject);
begin
PaintBox2.Canvas.Draw(MyImage2, 0, 0);
if PaintBox2.Tag = 1 then
begin
PaintBox2.Canvas.Brush.Style := bsClear;
PaintBox2.Canvas.Pen.Color := clRed;
PaintBox2.Canvas.Rectangle(PaintBox2.ClientRect);
end;
end;
Alternatively, you can derive a new class from TImage
and override its virtual Paint()
method to draw the rectangle after default drawing. For example:
type
TMyImage = class(TImage)
private
FShowRectangle: Boolean;
procedure SetShowRectangle(Value: Boolean);
protected
procedure Paint; override;
public
property ShowRectangle: Boolean read FShowRectangle write SetShowRectangle;
end;
procedure TMyImage.SetShowRectangle(Value: Boolean);
begin
if FShowRectangle <> Value then
begin
FShowRectangle := Value;
Invalidate;
end;
end;
type
TGraphicControlAccess = class(TGraphicControl)
end;
procedure TMyImage.Paint;
begin
inherited;
if FShowRectangle then
begin
with TGraphicControlAccess(Self).Canvas do
begin
Brush.Style := bsClear;
Pen.Color := clRed;
Rectangle(ClientRect);
end;
end;
end;
procedure TMyForm.MyImage1Click(Sender: TObject);
begin
MyImage1.ShowRectangle := true;
MyImage2.ShowRectangle := false;
end;
procedure TMyForm.MyImage2Click(Sender: TObject);
begin
MyImage1.ShowRectangle := false;
MyImage2.ShowRectangle := true;
end;
Upvotes: 9
Reputation: 277
I would recommend using a TRectangle. You can add an bitmap (bitmap, jpg, etc) via the Fill propery and set the Stroke property for the border.
You also can set the xRadius and yRadius properties for rounded borders.
Upvotes: -1