Recent

Author Topic: Adding border to component  (Read 6097 times)

Trenatos

  • Hero Member
  • *****
  • Posts: 537
    • MarcusFernstrom.com
Adding border to component
« on: May 04, 2016, 03:13:14 am »
I've looked around but not found a solution, is there a way to add a border to a component programmatically, or will I have to look into drawing lines and shapes?

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Adding border to component
« Reply #1 on: May 04, 2016, 02:55:55 pm »
Which specific component are you talking about ?

TComponent is non visual, so would not be suited to draw a border.

It's common to inherit from something like tcustomcontrol, which brings you canvas etc. that you can draw to. That control has a borderstyle property (which can be set or not), or alternatively you can use a canvas to f.e. draw a 3D frame.

Edit: add small example
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;
  9.  
  10.  
  11. type
  12.   TMyCustomControl = class(TCustomControl)
  13.   end;
  14.  
  15. type
  16.  
  17.   { TForm1 }
  18.  
  19.   TForm1 = class(TForm)
  20.     procedure FormCreate(Sender: TObject);
  21.   private
  22.     { private declarations }
  23.   public
  24.     { public declarations }
  25.     MyCustomControl : TMyCustomControl;
  26.   end;
  27.  
  28. var
  29.   Form1: TForm1;
  30.  
  31. implementation
  32.  
  33. {$R *.lfm}
  34.  
  35. { TForm1 }
  36.  
  37. procedure TForm1.FormCreate(Sender: TObject);
  38. begin
  39.   MyCustomControl := TMyCustomControl.Create(Self);
  40.   MyCustomControl.Parent := Self;
  41.   MyCustomControl.Left := 100;
  42.   MyCustomControl.Top := 100;
  43.   MyCustomControl.Width := 100;
  44.   MyCustomControl.Height := 100;
  45.   MyCustomControl.BorderStyle:= bsSingle; // bsNone;
  46. end;
  47.  
  48. end.
  49.  
« Last Edit: May 04, 2016, 03:17:25 pm by molly »

Trenatos

  • Hero Member
  • *****
  • Posts: 537
    • MarcusFernstrom.com
Re: Adding border to component
« Reply #2 on: May 04, 2016, 05:00:53 pm »
Hi Molly

I'm creating buttons, panels, and other things dynamically and am trying to add a border to show onclick to show the currently active item in an editor.

If I understand you right, I should be able to create a button and inherit from customcontrol, which has the ability to use a border or draw one?

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Adding border to component
« Reply #3 on: May 04, 2016, 05:32:16 pm »
Hi Trenatos,

If I understand you right, I should be able to create a button and inherit from customcontrol, which has the ability to use a border or draw one?
Nope. My answer was placed in another context, as your situation was not clear yet :-)

The 'normal' way to do that, and assuming you use standard LCL controls is to inherit _all_ your controls to be able to draw a custom border as you wish, or 'abuse' the design interface of the components (i do not have experience with the latter)

Quote
I'm creating buttons, panels, and other things dynamically and am trying to add a border to show onclick to show the currently active item in an editor.
Still not sure if you are using standard LCL controls.

If this is for using standard LCL controls _and_ has to work for Windows only, then i might be able to come up with a generic workaround.

Trenatos

  • Hero Member
  • *****
  • Posts: 537
    • MarcusFernstrom.com
Re: Adding border to component
« Reply #4 on: May 04, 2016, 06:05:23 pm »
I'm using standard controls for the moment but haven't decided what to use for long term, if images would work or more likely I'd have to make custom controls (Which I've never made before) to support scaling, borders, various shapes, etc.

It needs to work for both Windows and Mac.

I don't know if this information is of use for the answer, but maybe;
I'm working on a wysiwyg editor, I'm able to drag-and-drop items from a menu and create them dynamically in the editor area, they're clickable and sets an activeItem variable, but I need some kind of visual indicator of what the currently active item is, so if there's a better way to do it then I'm all ears.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Adding border to component
« Reply #5 on: May 04, 2016, 06:37:55 pm »
Well, in case using standard LCL controls and a TForm like component to place them on then you could perhaps use something like this:
Code: Pascal  [Select][+][-]
  1. unit unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;  // click event assigned to ControlClick
  16.     Edit1: TEdit; // click event assigned to ControlClick
  17.     procedure ControlClick(Sender: TObject);
  18.   private
  19.     { private declarations }
  20.   public
  21.     { public declarations }
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. { TForm1 }
  32.  
  33. procedure TForm1.ControlClick(Sender: TObject);
  34. const
  35.   FrameWidth = 2;
  36. Var
  37.   Rect : classes.TRect;
  38. begin
  39.   Self.Refresh;
  40.   With Sender as TControl do
  41.   begin
  42.     Rect.Top    := Top    - FrameWidth;
  43.     Rect.Left   := Left   - FrameWidth;
  44.     Rect.Bottom := (Top + Height)  + FrameWidth;
  45.     Rect.Right  := (Left + Width) + FrameWidth;
  46.     Canvas.Frame3D(Rect, clRed, clPurple, FrameWidth);
  47.     // or: Canvas.FrameRect(Rect);
  48.   end;
  49. end;
  50.  
  51. end.
  52.  
afaik the above should work on every supported platform (e.g. i have ditched the Windows only solution)

In case you are writing your own custom controls, then things can become a completely different ballgame ;-)

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Adding border to component
« Reply #6 on: May 04, 2016, 07:11:34 pm »
The following code shows another way to highlight focused controls. You may be able to adapt it for your needs.
Drop a TButton and a TEdit on a new form, double-click to make an OnCreate handler and complete it as follows:

Code: Pascal  [Select][+][-]
  1. unit mainBordered;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, Forms, Controls, Graphics, StdCtrls, types;
  9.  
  10. type
  11.  
  12.   { TBorder }
  13.  
  14.   TBorder = class(TGraphicControl)
  15.   private
  16.     FPenColor: TColor;
  17.     FBorderColor: TColor;
  18.   protected
  19.     procedure Paint; override;
  20.     procedure ControlEnter(Sender: TObject);
  21.     procedure ControlExit(Sender: TObject);
  22.   public
  23.     constructor {%H-}Create(AOwner: TForm;
  24.                        aWinControl: TWinControl;
  25.                        aBorderWidth: integer=3;
  26.                        aBorderColor: TColor=clBlue);
  27.   end;
  28.  
  29.   { TForm1 }
  30.  
  31.   TForm1 = class(TForm)
  32.     Button1: TButton;
  33.     Edit1: TEdit;
  34.     procedure FormCreate(Sender: TObject);
  35.   end;
  36.  
  37.   Procedure AddFocusBorder(aWinControl: TWinControl;
  38.                            aForm: TForm;
  39.                            aBorderWidth: integer=3;
  40.                            aColor: TColor=clBlue);
  41.  
  42. var
  43.   Form1: TForm1;
  44.  
  45. implementation
  46.  
  47. procedure AddFocusBorder(aWinControl: TWinControl; aForm: TForm;
  48.   aBorderWidth: integer; aColor: TColor);
  49. begin
  50.   TBorder.Create(aForm, aWinControl, aBorderWidth, aColor);
  51. end;
  52.  
  53. {$R *.lfm}
  54.  
  55. { TForm1 }
  56.  
  57. procedure TForm1.FormCreate(Sender: TObject);
  58. begin
  59.   AddFocusBorder(Button1, Self, 5, clMoneyGreen);
  60.   AddFocusBorder(Edit1, Self);
  61. end;
  62.  
  63. { TBorder }
  64.  
  65. constructor TBorder.Create(AOwner: TForm; aWinControl: TWinControl;
  66.   aBorderWidth: integer; aBorderColor: TColor);
  67. var
  68.   r: TRect;
  69. begin
  70.   Assert(aWinControl<>nil,'TBorder: non-existent control');
  71.   inherited Create(AOwner);
  72.   FBorderColor:=aBorderColor;
  73.   Canvas.Pen.Width:=aBorderWidth;
  74.   r:=aWinControl.BoundsRect;
  75.   if InflateRect(r, aBorderWidth, aBorderWidth) then
  76.     SetInitialBounds(r.Left, r.Top, r.Right-r.Left, r.Bottom-r.Top);
  77.   aWinControl.OnEnter:=@ControlEnter;
  78.   aWinControl.OnExit:=@ControlExit;
  79.   Parent:=AOwner;
  80. end;
  81.  
  82. procedure TBorder.ControlEnter(Sender: TObject);
  83. begin
  84.   FPenColor:=FBorderColor;
  85.   Repaint;
  86. end;
  87.  
  88. procedure TBorder.ControlExit(Sender: TObject);
  89. begin
  90.   FPenColor:=clBtnFace;
  91.   Repaint;
  92. end;
  93.  
  94. procedure TBorder.Paint;
  95. begin
  96.   Canvas.Pen.Color:=FPenColor;
  97.   Canvas.Rectangle(ClientRect);
  98. end;
  99.  
  100. end.
  101.  

Trenatos

  • Hero Member
  • *****
  • Posts: 537
    • MarcusFernstrom.com
Re: Adding border to component
« Reply #7 on: May 04, 2016, 11:34:00 pm »
Thanks guys, you sparked an idea.

I ended up creating a tshape, and then just update the size, parent, location on click, super simple but works for now.

 

TinyPortal © 2005-2018