Recent

Author Topic: Get initial property set in Object Inspector  (Read 314 times)

LazProgger

  • New member
  • *
  • Posts: 47
Get initial property set in Object Inspector
« on: December 08, 2018, 09:43:50 pm »
I have created an own component and set some initial properties using the object inspector. As an example, in one program property ABC is false, in another program ABC is true, initially.

During program execution, the user can change those values according to his needs. For example, he changes ABC from false to true.

Now, I want to offer a Reset function with which the user can reset ABC to its initial value.

Is there an easy way to retrieve those initial properties?

It should be done within the component itself, not by using an external procedure where those values are just set. So, for example with a procedure override within the component where I can store the defaults during initialization. I have tried to do that within Create or AfterConstruction, but in those procedures the properties from the Object Inspector are not available yet.

howardpc

  • Hero Member
  • *****
  • Posts: 2833
Re: Get initial property set in Object Inspector
« Reply #1 on: December 08, 2018, 11:15:51 pm »
Code: Pascal  [Select]
  1.  type
  2.  TDefault = class(TComponent)
  3.   private
  4.     FExampleBoolean: Boolean;
  5.     FExampleInteger: Integer;
  6.     function GetDefaultExampleBoolean: Boolean;
  7.     function GetDefaultExampleInteger: Integer;
  8.   public
  9.     constructor Create(AOwner: TComponent); override;
  10.     procedure ResetExampleBooleanToDefault;
  11.     procedure ResetExampleIntegerToDefault;
  12.     property ExampleBoolean: Boolean read FExampleBoolean write FExampleBoolean default False;
  13.     property ExampleInteger: Integer read FExampleInteger write FExampleInteger default 100;
  14.   end
  15.  
  16. implementation
  17.  
  18. function TDefault.GetDefaultExampleBoolean: Boolean;
  19. begin
  20.   Exit(False);
  21. end;
  22.  
  23. function TDefault.GetDefaultExampleInteger: Integer;
  24. begin
  25.   Exit(100);
  26. end;
  27.  
  28. constructor TDefault.Create(AOwner: TComponent);
  29. begin
  30.   inherited Create(AOwner);
  31.   ResetExampleBooleanToDefault;
  32.   ResetExampleIntegerToDefault;
  33. end;
  34.  
  35. procedure TDefault.ResetExampleIntegerToDefault;
  36. begin
  37.   FExampleInteger := GetDefaultExampleInteger;
  38. end;
  39.  
  40. procedure TDefault.ResetExampleBooleanToDefault;
  41. begin
  42.   FExampleBoolean := GetDefaultExampleBoolean;
  43. end;                            

Blaazen

  • Hero Member
  • *****
  • Posts: 2676
  • POKE 54296,15
    • Eye-Candy Controls
Re: Get initial property set in Object Inspector
« Reply #2 on: December 08, 2018, 11:19:48 pm »
There is virtual method Loaded; which is triggered after loading component from *.lfm.

But I don't understand this: for whom is your Reset method? For developers (who use your component) or for end-users?
Lazarus 2.1.0 r59757M FPC 3.3.1 r40507 x86_64-linux-qt Chakra, Qt 4.8.7/5.11.2, Plasma 5.14.2
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

lucamar

  • Sr. Member
  • ****
  • Posts: 494
Re: Get initial property set in Object Inspector
« Reply #3 on: December 08, 2018, 11:56:38 pm »
But I don't understand this: for whom is your Reset method? For developers (who use your component) or for end-users?

He said it is for the user:

During program execution, the user can change those values according to his needs. For example, he changes ABC from false to true.

Now, I want to offer a Reset function with which the user can reset ABC to its initial value.

Imagine, for example, a button "Reset to defaults". And yes, one of the best ways is to override the Loaded method or, for a container control (p.e. a TForm, TPanel, etc.), the LoadedAll one. Basically, something like this:

Code: Pascal  [Select]
  1. { Thoroughly untested !!!!!
  2.   Just an example of how it may look like. }
  3. interface
  4.  
  5. uses
  6.   Classes{, and whatever else};
  7.  
  8. type
  9.   TMyComponent = class(TComponent)
  10.   protected
  11.     FDefaultABC: Boolean;
  12.   private
  13.     {... lots of declarations ...}
  14.     FMyABC: Boolean;
  15.     procedure Loaded; override;
  16.   public
  17.     procedure ResetABC;
  18.     {... public methods, fields and properties ...}
  19.   published
  20.     property ABC: boolean read FMyABC write FMyABC;
  21.   end;
  22.  
  23.   {. . .}
  24.  
  25. implementation
  26.  
  27. procedure Loaded;
  28. begin
  29.   inherited Loaded;
  30.   FDefaultABC := FMyABC;
  31. end;
  32.  
  33. procedure ResetABC;
  34. begin
  35.   FMyABC := FDefaultABC;
  36. end;
  37.  
« Last Edit: December 08, 2018, 11:58:55 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 1.8.4/FPC 3.0.4 on:
(K)Ubuntu 11..16, Windows XP SP3 (Home/Prof.) and various DOS incarnations.

wp

  • Hero Member
  • *****
  • Posts: 5129
Re: Get initial property set in Object Inspector
« Reply #4 on: December 09, 2018, 12:22:49 am »
But this works only when the component is created at designtime. A runtime-created component does not load the lfm form, and therefore, Loaded is not called.

Why don't you use one of the prop storage components on palette "Misc" (TXMLPropStorage, TIniPropStorage, TJSONPropStorage)? When the form has reached a state before the user begins to interact (e.g. OnShow event) it can store all properties specified to an xml or ini file, and when the user needs to reset he reads the xml or ini file back and restores all the related properties. To use these components you must select the relevant properties via the SessionProperties dialog of the form.
« Last Edit: December 09, 2018, 12:42:37 am by wp »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

lucamar

  • Sr. Member
  • ****
  • Posts: 494
Re: Get initial property set in Object Inspector
« Reply #5 on: December 09, 2018, 12:46:55 am »
But this works only when the component is created at designtime. A runtime-created component does not load the lfm form, and therefore, Loaded is not called.

Yeah, that's true: If you create the component with something like:
Code: Pascal  [Select]
  1. MyComponent := TMyComponent.Create(Self);
there's no call to Loaded. But then you don't need it: you already know what's the default you're setting for that propery.

What the OP says he wants is that the user be able to restore the default set by the programmer at design-time: if the programmer elected to set it at creation time by code then it's already known and if it's set--as he said--in the object inspector then overriding Loaded makes it again known at that moment.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 1.8.4/FPC 3.0.4 on:
(K)Ubuntu 11..16, Windows XP SP3 (Home/Prof.) and various DOS incarnations.

LazProgger

  • New member
  • *
  • Posts: 47
Re: Get initial property set in Object Inspector
« Reply #6 on: December 09, 2018, 01:44:45 am »
There is virtual method Loaded; which is triggered after loading component from *.lfm.

Thanks! That was what I was searching for!


Imagine, for example, a button "Reset to defaults". And yes, one of the best ways is to override the Loaded method or, for a container control (p.e. a TForm, TPanel, etc.), the LoadedAll one. Basically, something like this:

Yes, I want to provide such a button. It would also be possible to do that with other solutions or provide properties such as PropertyCurrent and PropertyDefault, but I was searching for the easiest way, because otherwise it would be too much work, because I am using that component in different applications with different default values.

But this works only when the component is created at designtime. A runtime-created component does not load the lfm form, and therefore, Loaded is not called.

Good point! Good to know! Thanks for saying that! Luckily, I am only using that component created at runtime.

jamie

  • Hero Member
  • *****
  • Posts: 973
Re: Get initial property set in Object Inspector
« Reply #7 on: December 09, 2018, 05:54:21 pm »
WP has a great idea of using the already made Property Storage components and it would work nicely. One could simply
read the current values to be restored later...

 There is an issue with those components and that is, they only offer a FILE method and offer no STREAM
method to direct properties in/out of a memory stream or any other stream that is compatible.

 It would be nice if a stream could be introduced where as stream POSITION could also be used in a relative manner, incase
there are several to be streamed in order.

 Just an idea, maybe someone here to add that as an enhancement  :)

Alternate method for this particular case would be to create at runtime a background version of this
class and when you want to restore the working class to its defaults you could use the Assign!

So at startup..

 BackUp := TMyComonpent.Create(….);
 
 BackUp.Assign(CurentlyExistingTMyComponent);

----
 Later on in code for a reset.

CurrentlyExistingTMyComponent.Assign(BackUp);

That should work, maybe :D
« Last Edit: December 09, 2018, 06:12:41 pm by jamie »

jamie

  • Hero Member
  • *****
  • Posts: 973
Re: Get initial property set in Object Inspector
« Reply #8 on: December 09, 2018, 06:14:20 pm »
by the way, I always test my work in Production  :)