How to in-code copying design of UI element?

Hello coders!
I made beautiful button in Castle Editor:
image
Is there an easy way to copy parameters for a newly created in code button from an existing one?
Or I need to make a special function for coping needed for me parameters?

If you have an existing button, and want to copy it, you can create copies of it in code. You can use ComponentClone method from CastleComponentSerialize. Or, if you want to spawn a lot of such buttons, you can use TCastleComponentFactory:

In code:

var
  MyButtonFactory: TCastleComponentFactory;
begin
  MyButtonFactory := TCastleComponentFactory.Create(SomeOwner);
  MyButtonFactory.LoadFromComponent(MyButton);

  MyButton1 := MyButtonFactory.ComponentLoad(SomeOwner) as TCastleButton;
  MyButton1.Caption := 'Button 1 caption customized';
  SomeParent.InsertFront(MyButton1);

  MyButton2 := MyButtonFactory.ComponentLoad(SomeOwner) as TCastleButton;
  MyButton2.Caption := 'Button 2 caption customized';
  SomeParent.InsertFront(MyButton2);

You could also use RTTI (enumerate source properties, copy them using utilities from CastleInternalRttiUtils).

2 Likes

Thanks! It Working :slight_smile:
image
The only thing is that the TCastleButton.CustomFont parameter is not copied automated, I have to do it manually in code.

We do try to copy references to other components, like TCastleButton.CustomFont. But for this, at the moment of instantiation, (MyButtonFactory.ComponentLoad(SomeOwner) in example above) we must have the owner that knows how to resolve it. I.e. the SomeOwner must be also the owner of the font instance referred to by the TCastleButton.CustomFont.

Which indeed is not possible if you have loaded the design in TCastleView, using TCastleView.Url. In this case we hide the owner, deliberately, to have more reliable API (the FDesignLoadedOwner is private in TCastleView, and this means that published fields of view are reliably updated) and simpler implementation (TCastleView.TDesignOwner... make some assumptions and updates published fields of the view always). So we don’t give you possibility to pass proper SomeOwner.

Long story short: yes, this is a limitation of this approach for now. Sorry for long and useless explanation above :slight_smile: You cannot escape it, and workarounding it by manually assigning MyNewButton.CustomFont after clone is what you should do, for now. I’ll sleep on this and think can we offer something better, without breaking anything else.