Recent

Author Topic: TSpinEdit Min/Max behaviour  (Read 14959 times)

Muso

  • Sr. Member
  • ****
  • Posts: 357
TSpinEdit Min/Max behaviour
« on: January 03, 2022, 12:31:18 pm »
There is a major regression that the min/max values of edit fields is no longer respected:

- run the attached minimal program with Laz 2.0.12
result: everything is fine. When you enter a zero, it is immediately transformed to the set minimum "0.1" for the edit

- now run the same program with Laz 2.2.0git (I have rev lazarus_2_2_0-6-g4734343934, FPC 3.2.3 x86_64-win64-win32/win64 )

result: you get a division by zero because the set minimum is not respected.

I assume a regression because in the release notes I cannot find that the different behavior was intended.

Can anyone reproduce this?
« Last Edit: January 03, 2022, 12:40:56 pm by Muso »

Muso

  • Sr. Member
  • ****
  • Posts: 357
Re: TSpinEdit Min/Max behaviour
« Reply #1 on: January 03, 2022, 01:00:33 pm »
There is a major regression that the min/max values of edit fields is no longer respected:

I see now that the bug only occurs if a minimal value is set but no maximal value. If a maximal value is mandatory when a minimal value is set, this must appear somewhere in the Laz 2.2 release notes.

While we are at it, the IDE should be changed by automatically setting a maximal value of maybe 1.0 above the minimal value. As it is, I can e.g. set "11" as minimal value and "2" as maximum. The IDE should not allow this. It is not that users are stupid, but typos occur, in my example I wanted to set "1" as minimum but accidentally hit the 1 twice. It is therefore very valuable in getting feedback about my mistake.
Should/can I report this in the bug tracker?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11139
  • Debugger - SynEdit - and more
    • wiki
Re: TSpinEdit Min/Max behaviour
« Reply #2 on: January 03, 2022, 01:03:03 pm »
I don't think it should be mandatory.

I suggest to report it (if no one else has done yet).


« Last Edit: January 03, 2022, 01:47:36 pm by Martin_fr »

wp

  • Hero Member
  • *****
  • Posts: 12789
Re: TSpinEdit Min/Max behaviour
« Reply #3 on: January 03, 2022, 01:44:33 pm »
There is a major regression that the min/max values of edit fields is no longer respected [...] I assume a regression because in the release notes I cannot find that the different behavior was intended.
A TEdit control does not have a minimum/maximum value. Your are talking of T(Float)SpinEdit(Ex), aren't you?

There was a change some time ago in which the default of the maximum value has been changed to become Delphi compatible; the code incompatibility has been documented at https://wiki.freepascal.org/Lazarus_2.2.0_release_notes#T.28Float.29SpinEdit.28Ex.29_default_value_for_MaxValue_changed.

Muso

  • Sr. Member
  • ****
  • Posts: 357
Re: TSpinEdit Min/Max behaviour
« Reply #4 on: January 03, 2022, 02:01:54 pm »
There was a change some time ago in which the default of the maximum value has been changed to become Delphi compatible; the code incompatibility has been documented at https://wiki.freepascal.org/Lazarus_2.2.0_release_notes#T.28Float.29SpinEdit.28Ex.29_default_value_for_MaxValue_changed.

Stupid me that I did not find this.

However, there it is written
Quote
Old behaviour: the default value of MaxValue was 100

So the 100 was in effect. Why is this then not kept? I mean It is a nightmare to look through all my programs now to check if my 100 as max value now suddenly became a 0.
Can the the IDE please don't automatically change set values? It is OK that the new default is set for new elements but existing elements should not be changed automatically.

I also don't understand why the maximum can now be smaller than the minimum. This is very error-prone because as I wrote accidental inputs can happen quickly and you get no feedback from the IDE that because of a typo you SpinEdit is not limited at all.
So having max < min leads to the case that the limits are ignored so this should not be allowed because the user's will is obviously to have limits, otherwise he would not have entered them.
« Last Edit: January 03, 2022, 03:32:24 pm by Muso »

wp

  • Hero Member
  • *****
  • Posts: 12789
Re: TSpinEdit Min/Max behaviour
« Reply #5 on: January 03, 2022, 03:56:06 pm »
However, there it is written
Quote
Old behaviour: the default value of MaxValue was 100

So the 100 was in effect. Why is this then not kept? I mean It is a nightmare to look through all my programs now to check if my 100 as max value now suddenly became a 0.
Can the the IDE please don't automatically change set values? It is OK that the new default is set for new elements but existing elements should not be changed automatically.
This is not possible. When a property is declared with a default value and the property value is equal to the default value then the property is not written to the lfm file. So, when you open your project in the IDE and the streamer does not find this property in the lfm then the value of the property with which it was created is kept. In Laz 2.2+, the MaxValue after creation is 0, in older versions it was 100.

It is a nightmare to look through all my programs now to check if my 100 as max value now suddenly became a 0.
In all my programs the max very rarely is 100, and thus in the majority of cases it is different from the default of the old Laz versions and thus is written to the lfm. But I agree it is quite some effort to find all the changed cases in a large code base.

I also don't understand why the maximum can not be smaller than the minimum.
The current behaviour of unlimited spinning when Min <> 0 and Max = 0 appears to be a bug. Would you report it?

Not sure about the condition of Max < Min. It could also be interpreted to be intentional (although it does not appear to be very logical): The question is how the effect of a one-sided limit can be achieved, e.g. limit the MinValue, but define none for the MaxValue. Three possibilities come to my mind
- Make the MaxValue larger than the MinValue - I think this is confusing: Is the upper limit unbound? Or is the lower limit unbound?
- Add a new property FixedLimits = set of (fixedMin, fixedMax).
- Enter a "huge" value for MaxValue (e.g. MaxInt for the SpinEdit). Very simple, and looks fine.

I am not the author of these components, but I'd favour the third option.

I also tend to raise an exception when MaxValue < MinValue. But when? During streaming? This would lead to one of these nasty streaming errors which make it impossible to load a form... In the Object Inspector? But then the error will slip through at runtime. When at runtime? Could not find a good place after a quick search...
[/quote]

Muso

  • Sr. Member
  • ****
  • Posts: 357
Re: TSpinEdit Min/Max behaviour
« Reply #6 on: January 03, 2022, 05:24:03 pm »
This is not possible. When a property is declared with a default value and the property value is equal to the default value then the property is not written to the lfm file.

Thanks, I see now.

It is a nightmare to look through all my programs now to check if my 100 as max value now suddenly became a 0.

In my case it affected all spinEdits for percentages. So I fixed this using a text editor (jEdit) to fix all *.lfm files at once.

The current behaviour of unlimited spinning when Min <> 0 and Max = 0 appears to be a bug. Would you report it?

I will do so later today.

Not sure about the condition of Max < Min. It could also be interpreted to be intentional (although it does not appear to be very logical): The question is how the effect of a one-sided limit can be achieved, e.g. limit the MinValue, but define none for the MaxValue.

This is my proposal:
- if one limit is given but the other one not, the max value will internally be used. So if it is a TSpinEdit, this would be +MaxInt, in case of a TFloatSpinEdit, the it is +MaxDouble
So I propose almost the same as you, with the difference that the user doesn't have to enter the Max value manually.

I also tend to raise an exception when MaxValue < MinValue. But when?

Directly when entering the value in the IDE a dialog should pop up. I think of the same dialog that appears when you enter for a TSpinEdit a double as MinValue. Then the IDE also immediately tells you that you made a mistake.

Bart

  • Hero Member
  • *****
  • Posts: 5563
    • Bart en Mariska's Webstek
Re: TSpinEdit Min/Max behaviour
« Reply #7 on: January 03, 2022, 05:53:56 pm »
The current behaviour of unlimited spinning when Min <> 0 and Max = 0 appears to be a bug. Would you report it?

I will do so later today.

First of all, your observation is wrong.
If MinValue=-100 and MaxValue=0, the control is limited in it's spinning.

It is unlimited however if MinValue is NOT less than MaxValue.

From the sources:
Code: Pascal  [Select][+][-]
  1. function TCustomFloatSpinEdit.GetLimitedValue(const AValue: Double): Double;
  2. begin
  3.   Result := AValue;
  4.   //Delphi does not constrain when MinValue = MaxValue, and does if MaxValue < MinValue,
  5.   //but the latter makes absolutely no sense at all.
  6.   if FMaxValue > FMinValue then
  7.   begin
  8.     if Result < FMinValue then Result := FMinValue;
  9.     if Result > FMaxValue then Result := FMaxValue;
  10.   end;
  11. end;

Notice the comments in the code.

How do you think the behaviour should be if MinValue=10 and MaxValue=1?
Should only Values <=1 and Values>=10 be accepted?
Should MinValue and MaxValue be swapped (with or without a user notification)?

The names of these two properties to me at least suggest that a MaxValue should be greater than or equal to MinValue.

B.t.w. This has been implemented so for a long, long time.

Bart

Muso

  • Sr. Member
  • ****
  • Posts: 357
Re: TSpinEdit Min/Max behaviour
« Reply #8 on: January 03, 2022, 06:29:04 pm »
First of all, your observation is wrong.
If MinValue=-100 and MaxValue=0, the control is limited in it's spinning.
It is unlimited however if MinValue is NOT less than MaxValue.

Yes and this is what I wrote.
The regression bug is therefore a combination of these two things:
- I have SpinEdits for percentages, therefore I only set a MinValue, no MaxValue
- now the unset MaxValue is interpreted as 0, so in fact I suddendly have MinValue > 0, MaxValue = 0 and in this state the spin is unlimited

Finding this, and fixing cost me a lot of time because it is very confusing.

The solution would be as I or wp proposed.

How do you think the behaviour should be if MinValue=10 and MaxValue=1?

- the IDE should not allow this setting - the same way as it for example does not allow to set a double as MinValue for the integer-based TSpinEdit.
- when you set a MinValue > MaxValue at runtime, Lazarus should output at least a warning when compiling.

Bart

  • Hero Member
  • *****
  • Posts: 5563
    • Bart en Mariska's Webstek
Re: TSpinEdit Min/Max behaviour
« Reply #9 on: January 03, 2022, 10:45:16 pm »
In the past setting MaxValue < MinValue was prohibited, but lead to unwanted side effects (bugs) upon loading the component from LFM, so this was abandoned.
See T(Float)SpinEditEx MaxValue is no longer enforced to be >= MinValue

About default MaxValue now being 0 instead of 100: this was also reported in the same release notes.

Bart

Bart

  • Hero Member
  • *****
  • Posts: 5563
    • Bart en Mariska's Webstek
Re: TSpinEdit Min/Max behaviour
« Reply #10 on: January 03, 2022, 10:52:33 pm »
This is my proposal:
- if one limit is given but the other one not, the max value will internally be used. So if it is a TSpinEdit, this would be +MaxInt, in case of a TFloatSpinEdit, the it is +MaxDouble

What does that mean: "if one limit is given but the other one not"?
MinValue and MaxValue both are give at any time.

Bart

Bart

  • Hero Member
  • *****
  • Posts: 5563
    • Bart en Mariska's Webstek
Re: TSpinEdit Min/Max behaviour
« Reply #11 on: January 03, 2022, 10:59:20 pm »
Directly when entering the value in the IDE a dialog should pop up. I think of the same dialog that appears when you enter for a TSpinEdit a double as MinValue. Then the IDE also immediately tells you that you made a mistake.

So now you are in fact forcing the user to change the values of MinValue and MaxValue in a particular order, depending on what the situation before change was, and what the end result should be.

E.g. MinValue=100, MaxValue=200. I want it to be MinValue=-50, MaxValue=50.
Since MaxValue comes alphabetically before MinValue it will be above MinValue in the OI.
Therefore it it rather natural to first change MaxValue into 50, but now the IDE will show me an error message?

Bart

wp

  • Hero Member
  • *****
  • Posts: 12789
Re: TSpinEdit Min/Max behaviour
« Reply #12 on: January 03, 2022, 11:10:47 pm »
What does that mean: "if one limit is given but the other one not"?
I think he means, for example, to set only a lower limit, so that the values can only increase above this limit up to "infinity", but not below it. Likewise with an upper limit.

If we had specified the TSpinEdit default values for MaxValue to be MaxInt and that for Minvalue to be -(MaxValue+1) the user would have to change only a single value to achieve this behaviour. If he'd set MinValue=5 and keep MaxValue at this default (MaxInt) he would be able to enter any value >= 5, but nothing smaller. Now he must set both Maxvalue and MinValue for this purpose. No big problem, I think...

wp

  • Hero Member
  • *****
  • Posts: 12789
Re: TSpinEdit Min/Max behaviour
« Reply #13 on: January 03, 2022, 11:14:16 pm »
Since MaxValue comes alphabetically before MinValue it will be above MinValue in the OI.
Therefore it it rather natural to first change MaxValue into 50, but now the IDE will show me an error message?
Very good point. I hate software which thinks for me while I am typing.

Bart

  • Hero Member
  • *****
  • Posts: 5563
    • Bart en Mariska's Webstek
Re: TSpinEdit Min/Max behaviour
« Reply #14 on: January 04, 2022, 12:29:25 am »
What does that mean: "if one limit is given but the other one not"?
...
If we had specified the TSpinEdit default values for MaxValue to be MaxInt and that for Minvalue to be -(MaxValue+1) the user would have to change only a single value to achieve this behaviour.

Aha, I see.
If we would have had total freedom to desing from the ground up it might have been this way.
Unfortunately we have to take the behaviour of Delphi into account (that does not mean we also have to implement their bugs as well though).

Either way, none of this can be resolved without breaking backwards compatibility.
(As we clearly already did because we had to fix bugs and conform to defualt valuus for MinValue/MaxValue that Delphi uses.)

Bart

 

TinyPortal © 2005-2018