Recent

Author Topic: Embedded component above Owner  (Read 6345 times)

mig-31

  • Sr. Member
  • ****
  • Posts: 307
Embedded component above Owner
« on: February 19, 2015, 02:46:59 pm »
What I should to do create new component with embedded TEdit above TPicture (Owner).
I want to place TEdit outside the TPicture(Owner) and manipulate with TEdit position by set Top and Left Property.
When I try to do it like this
Code: [Select]
TEmbeddedEdit.Top := Top - 20;

in constructor I don't see TEdit.
Lazarus 2.2.6 - OpenSuse Leap 15.4, Mageia 8, CentOS 7

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Embedded component above Owner
« Reply #1 on: February 19, 2015, 04:07:35 pm »
You need to show the entire code for your component in order to point you towards improvements that accomplish what you want to see.

mig-31

  • Sr. Member
  • ****
  • Posts: 307
Re: Embedded component above Owner
« Reply #2 on: February 19, 2015, 04:28:12 pm »
Code: [Select]
unit EditImage;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls,StdCtrls;

type

  { TEditImage }

  TEditImage = class(TImage)
  private
    FAboveEdit: TEdit;
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner:TComponent);override;
  published
    { Published declarations }
    property AboveEdit:TEdit read FAboveEdit;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Misc',[TEditImage]);
end;

{ TEditImage }

constructor TEditImage.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  with GetControlClassDefaultSize do
    SetInitialBounds(0, 0, CX, CY);
  FAboveEdit:=TEdit.Create(Self);
  FAboveEdit.Parent:=Parent;
  FAboveEdit.SetSubComponent(true);
  FaboveEdit.Name:='Edit1';
  FAboveEdit.Text:='Edit1';
    //how to sow it
  FAboveEdit.Top:=Top - 20;
end;

end.
Lazarus 2.2.6 - OpenSuse Leap 15.4, Mageia 8, CentOS 7

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Embedded component above Owner
« Reply #3 on: February 19, 2015, 05:15:35 pm »
Here is one way to make such a component. It's pretty crude, but I hope contains enough basic ideas to get you started on the right track.

Code: [Select]
unit ImageAndEdit;

{$mode objfpc}{$H+}

interface

uses
  Classes, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;

type

  TPosition = (poAbove, poBelow);

  { TImageAndEdit }

  TImageAndEdit = class(TCustomControl)
  strict private
    FEditPosition: TPosition;
    FImage: TImage;
    FEdit: TEdit;
    FSpacing: integer;
    procedure SetEditPosition(AValue: TPosition);
    procedure SetSpacing(AValue: integer);
    procedure PositionChildren;
  protected
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property EditBox: TEdit read FEdit;
    property Image: TImage read FImage;
    property EditPosition: TPosition read FEditPosition write SetEditPosition default poAbove;
    property Spacing: integer read FSpacing write SetSpacing default 6;
  end;

procedure Register;

implementation


procedure Register;
begin
  RegisterComponents('Misc',[TImageAndEdit]);
end;

{ TImageAndEdit }

procedure TImageAndEdit.SetEditPosition(AValue: TPosition);
begin
  if FEditPosition=AValue then
    Exit;
  FEditPosition:=AValue;
  PositionChildren;
end;

procedure TImageAndEdit.SetSpacing(AValue: integer);
begin
  if FSpacing=AValue then
    Exit;
  FSpacing:=AValue;
  PositionChildren;
end;

procedure TImageAndEdit.PositionChildren;
var
  w, h, t: integer;
begin
  w:=ClientWidth;
  h:=ClientHeight;
  t:=23 + FSpacing;
  case FEditPosition of
    poAbove: begin
      FEdit.SetBounds(0, 0, w, 23);
      FImage.SetBounds(0, t, w, h-t);
    end;
    poBelow: begin
      FImage.SetBounds(0, 0, w, h-t);
      FEdit.SetBounds(0, h-23, w, 23);
    end;
  end;
end;

procedure TImageAndEdit.Paint;
begin
  Canvas.Brush.Color:=Color;
  Canvas.FillRect(ClientRect);
  inherited Paint;
end;

constructor TImageAndEdit.Create(AOwner: TComponent);
var
  wi, hi: integer;
begin
  inherited Create(AOwner);
  FSpacing:=6;
  FEditPosition:=poAbove;

  FImage:=TImage.Create(Self);
  FImage.SetSubComponent(True);
  FEdit:=TEdit.Create(Self);
  FEdit.SetSubComponent(True);

  FImage.GetPreferredSize(wi, hi);
  FImage.SetInitialBounds(0, 0, wi, hi);
  FEdit.SetInitialBounds(0, 0, wi, 23);
  SetInitialBounds(0, 0, wi, 23+FSpacing+hi);
  PositionChildren;
  FEdit.Parent:=Self;
  FImage.Parent:=Self;
end;

end.


Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11812
  • Debugger - SynEdit - and more
    • wiki
Re: Embedded component above Owner
« Reply #4 on: February 19, 2015, 05:36:48 pm »
Quote
Code: [Select]
constructor TEditImage.Create(AOwner: TComponent);
begin
...
  FAboveEdit.Parent:=Parent;

Parent is not yet set at this time.

Override SetParent, and put the statement there

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Embedded component above Owner
« Reply #5 on: February 19, 2015, 06:27:11 pm »
Thanks Martin, you're quite right.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Embedded component above Owner
« Reply #6 on: February 19, 2015, 06:36:04 pm »
I suggest that you Override:
1- Loaded, it is called when all properties (like Parent and Top) are set, to set the properties of FAboveEdit.
2-SetParent to follow and apply the changes to FAboveEdit.
3-SetBounds (or ChangeBounds) to track Top changes.

Maybe also Notification to track deletion of FAboveEdit. There are more details like to hide/show both controls when the image visibility changed CM_VISIBLECHANGED message needs to be implemented. Check TCustomLabeledEdit class for a good example, although it uses anchors to position the label.

mig-31

  • Sr. Member
  • ****
  • Posts: 307
Re: Embedded component above Owner
« Reply #7 on: February 20, 2015, 10:25:31 am »
Thank you for inspiration.
I understand, that better to use CustomControl as container for two elements.

I want to create components for creation of basic electrical circuit schema, with TEdit above such electrical component (resistor, capacitor etc.) as input for user .

For first time I think, that I can do it with TEdit and TImage, but propabley TPaintBox is more suitable?
Lazarus 2.2.6 - OpenSuse Leap 15.4, Mageia 8, CentOS 7

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Embedded component above Owner
« Reply #8 on: February 20, 2015, 10:50:27 am »
Thank you for inspiration.
I understand, that better to use CustomControl as container for two elements.

I want to create components for creation of basic electrical circuit schema, with TEdit above such electrical component (resistor, capacitor etc.) as input for user .

For first time I think, that I can do it with TEdit and TImage, but propabley TPaintBox is more suitable?

Before going any farther with this design do your self a favor, open inkscape and draw a couple of those objects in a page, with their editors and all and see how it really looks and feels. This is a design that will fill the limited screen space with too much unrelated items for the design. In any case if you do decide to go forward with this then it depends on your requirements about the designer and objects. Please post them so we can better understand.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

mig-31

  • Sr. Member
  • ****
  • Posts: 307
Re: Embedded component above Owner
« Reply #9 on: February 20, 2015, 01:01:18 pm »
For first time I need it only in design time.
I need to show to user electrical schema, which is frozen, with editable component parameter for next measurement calculation.

I think the simplest way is to load component picture into TImage and align TEdit to it.
Lazarus 2.2.6 - OpenSuse Leap 15.4, Mageia 8, CentOS 7

 

TinyPortal © 2005-2018