Recent

Author Topic: Reload a Frame instance while preserving custom properties  (Read 1968 times)

Nel_Fie

  • Jr. Member
  • **
  • Posts: 53
Reload a Frame instance while preserving custom properties
« on: August 31, 2024, 02:48:56 pm »
Unless there's already a way to do it that I haven't found yet, I think it would be very useful to have a way to reload/refresh an instance of a custom TFrame, ideally while preserving custom properties, event bindings, etc...

As it currently is, the only way I know to achieve this requires deleting the Frame instance and creating a new one, then reapplying all the custom properties by hand, which can get a bit tedious. So it would be a really nice time-saver to have this whole process automated as an action in the right-click menu of Frame instances, for example.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8091
Re: Reload a Frame instance while preserving custom properties
« Reply #1 on: August 31, 2024, 03:23:52 pm »
Do all your configuration of the content of a frame when the frame is being edited by the IDE. Instantiating a frame onto a form and then editing some of its properties is a recipe for disaster, to the extent that you might need to fix it by editing the form's .lfm as a text file.

Please take that as a statement of fact: I'm not attempting to defend the situation, or attempting to defend the fact that an instantiated frame is not read-only (at least by default).

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

mas steindorff

  • Hero Member
  • *****
  • Posts: 553
Re: Reload a Frame instance while preserving custom properties
« Reply #2 on: September 01, 2024, 01:25:50 am »
as a TFrame, you can customize it's code and add your own "reset" or return to default function.  since a TFrame can be  made up of different components, which ones are you trying to return to "default"? 
 
windows 10 &11, Ubuntu 21+ IDE 3.4 general releases

Nel_Fie

  • Jr. Member
  • **
  • Posts: 53
Re: Reload a Frame instance while preserving custom properties
« Reply #3 on: September 01, 2024, 02:30:23 pm »
Do all your configuration of the content of a frame when the frame is being edited by the IDE. Instantiating a frame onto a form and then editing some of its properties is a recipe for disaster, to the extent that you might need to fix it by editing the form's .lfm as a text file.

Please take that as a statement of fact: I'm not attempting to defend the situation, or attempting to defend the fact that an instantiated frame is not read-only (at least by default).

MarkMLl

Huh. And here I thought being able to modify an instantiated frame was very much intended, as a way to adapt it to the specific context of the instance.

as a TFrame, you can customize it's code and add your own "reset" or return to default function.  since a TFrame can be  made up of different components, which ones are you trying to return to "default"? 
 

I think we're talking about different things, or else I'm not sure I understand what you mean. I'm not talking about resetting the instance of a Frame to a "default" at runtime, but about re-loading/re-inserting it in the IDE, from the original unit/files that describe that TFrame, in such a way that I would also implement any modifications made to the original since it was first instantiated.

The current situation is a bit simpler than I originally thought, however: an instance (or at least parts of it, such as an added or removed component) can be reloaded by closing the Form or Frame containing the instance and everything related to it, then opening it again. A bit of a hassle, but better than having to recreate the instance entirely.

EDIT: Scratch that. I just tried it again, and now I'm getting an "The LFM file contains invalid properties" error for the Form containing the instance. All the "invalid" properties are related to the instantiated frame. So, not an entirely safe method.
« Last Edit: September 01, 2024, 02:34:01 pm by Nel_Fie »

cdbc

  • Hero Member
  • *****
  • Posts: 1757
    • http://www.cdbc.dk
Re: Reload a Frame instance while preserving custom properties
« Reply #4 on: September 01, 2024, 02:56:24 pm »
Hi
1) create you frame and design it visually, DO NOT PUT IT ON THE FORM!
2) when satisfied with your frame, create it in code on form startup,
    ONLY IN CODE I.E.: DYNAMICALLY!
3) It's ok to design and redesign your frame(only) in oi but don't instantiate it
    on the form.
This is a proven way to handle your predicament.
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

MarkMLl

  • Hero Member
  • *****
  • Posts: 8091
Re: Reload a Frame instance while preserving custom properties
« Reply #5 on: September 01, 2024, 03:15:56 pm »
Hi
1) create you frame and design it visually, DO NOT PUT IT ON THE FORM!
2) when satisfied with your frame, create it in code on form startup,
    ONLY IN CODE I.E.: DYNAMICALLY!
3) It's ok to design and redesign your frame(only) in oi but don't instantiate it
    on the form.
This is a proven way to handle your predicament.
Regards Benny

I generally agree. You can, at a pinch, get away with instantiating at design time BUT the risk of changing its properties is substantial and- as I've said- tidying up is a hassle.

There are two areas in which frames really shine. The first is when they can be populated with a selection of controls which are configured at design time: I've currently got something running in front of me which has a twice-instantiated frame containing a TMemo (for monochrome text logging) and a single frame containing a TRichMemo (for coloured text logging): obviously these were almost entirely set up at design time.

The second if when you instantiate a new frame to populate a page of a tabbed notebook etc. when added.

I can't remember /why/ frames aren't, at least by default, read-only: it might be for Delphi compatibility.

So: they're very useful, but have to be used carefully.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10663
  • Debugger - SynEdit - and more
    • wiki
Re: Reload a Frame instance while preserving custom properties
« Reply #6 on: September 01, 2024, 04:04:39 pm »
For now the best I am aware of, is a workaround.

Let's say you have you TFrameFoo on your TFormBar. And then you Edit TFrameFoo...

Now it may actually depend what you edited....
But what I usually do is:
- Make a backup
- Open TFormBar (and any form that has the frame)
- From the designer context menu "View source (lfm)"
- find the frame
Code: Text  [Select][+][-]
  1. inline FooFrame: TFooFrame
- within the frame remove all entries, except those that I have intentionally set, to modify the frame

A lot of it will just be Top,Left,Height,Width. And nested objects, with only those fields.

- Save the lfm, close the editor holding the lfm, open the form with F12 again
All should be updated.


Nel_Fie

  • Jr. Member
  • **
  • Posts: 53
Re: Reload a Frame instance while preserving custom properties
« Reply #7 on: September 02, 2024, 01:53:33 pm »
Hi
1) create you frame and design it visually, DO NOT PUT IT ON THE FORM!
2) when satisfied with your frame, create it in code on form startup,
    ONLY IN CODE I.E.: DYNAMICALLY!
3) It's ok to design and redesign your frame(only) in oi but don't instantiate it
    on the form.
This is a proven way to handle your predicament.
Regards Benny

Thank you for the recommendation. I guess I'll have to do it this way going forward.

It's a bit annoying that I basically can't see what the instantiated frame looks like in the IDE, though. 

For now the best I am aware of, is a workaround.

Let's say you have you TFrameFoo on your TFormBar. And then you Edit TFrameFoo...

Now it may actually depend what you edited....
But what I usually do is:
- Make a backup
- Open TFormBar (and any form that has the frame)
- From the designer context menu "View source (lfm)"
- find the frame
Code: Text  [Select][+][-]
  1. inline FooFrame: TFooFrame
- within the frame remove all entries, except those that I have intentionally set, to modify the frame

A lot of it will just be Top,Left,Height,Width. And nested objects, with only those fields.

- Save the lfm, close the editor holding the lfm, open the form with F12 again
All should be updated.



I'm not sure if you're answering to my original post, or to the later "The LFM file contains invalid properties" error. If it's the latter, Lazarus managed to fix it itself by deleting the properties.

If it's the former, I'm afraid your solution is actually more work, or at least an equivalent amount of work to just deleting the instance and re-inserting it from scratch. Unless you mean that the frame instance will update itself automatically in perpetuity, if the process you describe is performed once?

mas steindorff

  • Hero Member
  • *****
  • Posts: 553
Re: Reload a Frame instance while preserving custom properties
« Reply #8 on: September 03, 2024, 03:39:44 am »
I can not find it now but there was a post or wiki page on how to refresh a TFrame at design time. The 1st option was to close the IDE and reopen it but there were other better options offered.  I think one was to save everything and then just reopen the project without closing the IDE.  in my memory, there was even a simpler [F5] like fix with IDE 3.4 or abouts but I may be wrong.
I tend to use cdbc's approach in my work since mine then to be reused in my code and need to be created at run time so each can be customized at run time (wording and coded options).

windows 10 &11, Ubuntu 21+ IDE 3.4 general releases

Nel_Fie

  • Jr. Member
  • **
  • Posts: 53
Re: Reload a Frame instance while preserving custom properties
« Reply #9 on: September 04, 2024, 09:41:55 am »
I can not find it now but there was a post or wiki page on how to refresh a TFrame at design time. The 1st option was to close the IDE and reopen it but there were other better options offered.  I think one was to save everything and then just reopen the project without closing the IDE.  in my memory, there was even a simpler [F5] like fix with IDE 3.4 or abouts but I may be wrong.
I tend to use cdbc's approach in my work since mine then to be reused in my code and need to be created at run time so each can be customized at run time (wording and coded options).

I can confirm that closing and reopening forms/projects does work some time, but I've had it cause some "invalid properties" errors in .lfm files as well. These haven't been catastrophic yet since Lazarus can clean them up by itself if prompted, and everything seemed to work as intended afterwards, but it can be a bit alarming for someone who doesn't know.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10663
  • Debugger - SynEdit - and more
    • wiki
Re: Reload a Frame instance while preserving custom properties
« Reply #10 on: September 04, 2024, 10:56:14 am »

I'm not sure if you're answering to my original post, or to the later "The LFM file contains invalid properties" error. If it's the latter, Lazarus managed to fix it itself by deleting the properties.

If it's the former, I'm afraid your solution is actually more work, or at least an equivalent amount of work to just deleting the instance and re-inserting it from scratch. Unless you mean that the frame instance will update itself automatically in perpetuity, if the process you describe is performed once?

It was meant a reply to you first post.
Though it depends on what you meant by "refresh"

I assume that you changed the frame, but those changes aren't visible in the form on which the frame has already been added.

Then it depends what changes you made to the frame.

- Added a new component (and saved the frame)
=> just close and re-open the form

- Removed a component from the frame
=> This may work by reopening the form. BUt it may give an error then you need to remove the "inherited" entry for the deleted component from the forms lfm (which contains the frame lfm too)

=> Moved a component / change some other property (color, caption, ...)
Movement may not follow, because the frame saved the old coordinates to the frame lfm, and sticks to them. So you need to edit away the old coordinates.
Other properties may or may not need editing.

By Editing, you can however keep other changes. Such as caption for frame elements, that you intentionally modified in the form. And you keep settings of the frame itself, eg how it is anchored inside the form.



So when I have any such issue, I usually open the lfm, and remove any component within the frame, unless I have reason to keep it.  This is usually one or two blocks of lfm code to delete.
Then reopening the form and the frame will have its correct new state. And it will still be correctly place in form1 and have its events. (events on the frame, if there were events on components inside the frame, then those components had to be kept in the "delete" step, and maybe only had it's left/top removed).

MarkMLl

  • Hero Member
  • *****
  • Posts: 8091
Re: Reload a Frame instance while preserving custom properties
« Reply #11 on: September 04, 2024, 11:01:06 am »
So when I have any such issue, I usually open the lfm, and remove any component within the frame, unless I have reason to keep it.  This is usually one or two blocks of lfm code to delete.
Then reopening the form and the frame will have its correct new state. And it will still be correctly place in form1 and have its events. (events on the frame, if there were events on components inside the frame, then those components had to be kept in the "delete" step, and maybe only had it's left/top removed).

I think it makes life easier to always have the frame occupy a presized panel etc., so that it can be removed and replaced with minimal customisation.

Martin, can you remember why the consensus was that a frame shouldn't default to R/O after being instantiated to a form? Was it the "Delphi compatibility" bogeyman?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10663
  • Debugger - SynEdit - and more
    • wiki
Re: Reload a Frame instance while preserving custom properties
« Reply #12 on: September 04, 2024, 11:18:22 am »
Martin, can you remember why the consensus was that a frame shouldn't default to R/O after being instantiated to a form? Was it the "Delphi compatibility" bogeyman?

I think the question is the wrong way round. By default any component (and that includes frames) are editable.
So the question is why not "why was it decided otherwise", but it is "why wasn't it decided to be different" => well because nobody ever thought of it.

Also, there may be cases were you need to edit a frame and propagate the changes.

The problem is that properties are streamed to the lfm, even if they shouldn't....

MarkMLl

  • Hero Member
  • *****
  • Posts: 8091
Re: Reload a Frame instance while preserving custom properties
« Reply #13 on: September 04, 2024, 11:28:31 am »
So the question is why not "why was it decided otherwise", but it is "why wasn't it decided to be different" => well because nobody ever thought of it.

It's definitely been raised informally, i.e. here or on the ML.

I think the significant thing is that frames are the only case (unless datamodules?) where something described by a .lfm is instantiated into a second one which encapsulates it.

And I believe I said "R/O by default", i.e. there might well be cases where an experienced user decides to accept the risk that manual correction would be needed.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10663
  • Debugger - SynEdit - and more
    • wiki
Re: Reload a Frame instance while preserving custom properties
« Reply #14 on: September 04, 2024, 11:59:49 am »
Well, I can't comment on whatever was raised, as I am not aware of it....
Also, at this point, I only express my personal opinion.

1) if the instantiated frame was streamed properly RO may not (or very rarely) be needed.  (EDIT: after writing point 2, it is unclear if you want the original, or the embedded to be RO?)

2) RO does not solve the issue either. Unless you mean the original (not embedded source definition) of a frame must be read only / rather than the instance).
Btw, the conceptual issue then remains with form inheritance... (afaik).




I have just recently worked with frames, and (after fixing the streaming issues) I was able to just edit a frame (ok, I only do certain edits) and I don't even need to touch the forms (or frames that nest the edited frame), and yet the compiled exe has all the changes.

So there are large parts that (nearly) work. I would not want to make them less reachable by hiding them behind some RO that then needs to be turned off to get the full experience.

1) Ideally, if I drop a frame (that has components) onto a form, the form would have only something like (mock up)
Code: Text  [Select][+][-]
  1. inline frame: Tframe
  2.   Top: 1
  3.   Left: 22
  4. end
Nothing else. Then if I edit the frame, it will not cause any conflicts. I can add,remove,change, and it all propagates.

Care must be taken if the form with an instance of the frame is open, because if such an open form doesn't follow changes, then it will mess up if it gets saved....
=> So that is 2 fixes/features missing. (there are more)


It become then complicated, if I changed the caption of a button inside the instantiated frame.
- That button will (and should) no longer follow caption changes in the original frame (that is ok).
- But if the entire button is deleted in the frame, then that causes an issue (and that is harder to solve).
  Because then all forms must be searched, for having a modified instance of that button, and it needs to be removed there too.
  But "all forms" can be in many projects, if the frame is in a package.

That is the same with (custom) components, if a published property is removed.


I haven't got a full list of other issues, but the above are the ones that I usually experience. And (other than the delete) they are solvable (though as usual, someone needs to do the work). Well, some parts of "solvable" may be much harder to solve that they would at first appear...


 

TinyPortal © 2005-2018