Recent

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

Muso

  • Sr. Member
  • ****
  • Posts: 356
Re: TSpinEdit Min/Max behaviour
« Reply #30 on: January 04, 2022, 06:40:56 pm »
And yet you filed a bugreport...

Because wp encouraged me, see his first posts in the thread

  • Did you read the release notes before you upgraded?
  • Did you do regression test of your software before you enrolled the version built with Laz 2.2  into production?

Yes and yes  :)
Some of the cool new TAchart features in Laz 2.2 were kindly built in by wp, triggered by me. In fact I worked with Laz 2.2 and 2.0 parallel for a year. I did not encounter issues. I found some FPdebugger issues after I made the switch and Martin kindly already fixed them.

Concerning the release notes. I read them in summer the last time. The point is that it was not clear that when I see a "100" form MaxValue in Laz 2.0, this info is not in the *.lfm file. This is what I learned in this thread. Also that the edit can become unlimited when max < min is something I first learned here.
« Last Edit: January 04, 2022, 06:52:29 pm by Muso »

Muso

  • Sr. Member
  • ****
  • Posts: 356
Re: TSpinEdit Min/Max behaviour
« Reply #31 on: January 04, 2022, 06:47:53 pm »
I guess your calculation is triggered by the OnChange of the control?
If so, that is a bad idea IMO.

OK. This is new to me.
I program also with Qt and there all the limit handling is done by Qt directly. So before the "OnChanged" signal is evaluated, the limit checker does its work. So entering a value out of the limits does not trigger an OnChange event.

How is this with LCL?

In my case it is a motor control. With less than 0.1 % of it max. power, it doesn not spin, with negative values, it would spin in the other direction. Therefore I simply set the MinValue to "0.1". I wrote this software about 2 years ago and up to now it worked well - when you try to enter a zero or minus sign, you cannot do this and the onChanged event is not triggered - like it is with Qt.

So did I made a big mistake for a long time?

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: TSpinEdit Min/Max behaviour
« Reply #32 on: January 04, 2022, 06:49:35 pm »
Yes and yes  :)

But, as it turns out not thoroughly enough  O:-)

Concerning the release notes. I read them in summer the last time. The point is that it was not clear that when I see a "100" form MaxValue in Laz 2.0, this info is not in the *.lfm file.
This is what I learned in this thread.

Well, that is the whole concept of default values for properties.

Also that the edit can become unlimited when max < min is something I first learned here.

Fortunately you are never to old to learn?
Did you read wp's description of how this works in D7?
I hope you can agree that the way it "works" there is a bit isiotic, to say the least?

Again: it is unfortunate that you are hit by the combination of 2 backwards incompatible changes in this control.

Bart

Muso

  • Sr. Member
  • ****
  • Posts: 356
Re: TSpinEdit Min/Max behaviour
« Reply #33 on: January 04, 2022, 07:00:51 pm »
Did you read wp's description of how this works in D7?

I don't know what is the recent Delphi version. D7 is quite old.
However:

> * MaxValue = 0, MinValue = 0 --> unlimited spinning

Makes sense because you need a state in which the edit is unlimited.

> * MaxValue=-10, Minvalue=10 --> ok, there is no error message, but also, there is no unlimited spinning: clicking the spin buttons makes the edit jump between -10 and 10 without the intermediate values.

Understandable as well because what else would you do if max < min is allowed? In my opinion the good point with this implementation is that that is makes the right assumption: the user explicitly set a limit, so the user want a limit. He might have set max < min just because of a typo or so (e.g. setting min to "11" instead of the intended "1"). When testing the program he quickly sees the issue.

So please don't beat me that I find the implementation reasonable. I should better say since max < min is not forbidden, I don't have a better idea for an implementation.
« Last Edit: January 04, 2022, 07:21:28 pm by Muso »

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: TSpinEdit Min/Max behaviour
« Reply #34 on: January 04, 2022, 07:07:25 pm »

OK. This is new to me.
I program also with Qt and there all the limit handling is done by Qt directly. So before the "OnChanged" signal is evaluated, the limit checker does its work. So entering a value out of the limits does not trigger an OnChange event.

How is this with LCL?

AFAIK the OnChange is invoked whenever the user makes a change in the control, so when the text in the control ie e.g. '1.0'  and the user types a '0' before the '1', then an OnChange should be triggered.


(If that is not the case in QT, then this looks like a bug to me.)

On Windows it is possible to paste arbitrary text into the control, or completely clear the control.
When you query Value, this will hold a value of course (Value is not of a nullable type), but that may at this point in time not be what you expect.
E.g. the control currently reads '1.1', I manually (by typing) change that to '21.0', then place the caret behind the '0' and press Backspace until the control is empty.
When the control is empty, Value will be 2.0. Is this what you expected?

Also: inserting zero's before the first digit repeatedly (most likely by accident) will keep on triggering OnChanges, but the Value never changes.

This can be avoided by setting EditorEnabled to False (but I do not know if this property exists in Laz 2.2).
Currently I think however that it is not possible to distinguish between an OnChange fired because the spinners were clicked (Value is always correct) or by editing the text (Value may not be what you expect).

In a perfect world the control should maybe have a "OnValueChanged" event?

Bart

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: TSpinEdit Min/Max behaviour
« Reply #35 on: January 04, 2022, 07:20:54 pm »
I program also with Qt and there all the limit handling is done by Qt directly. So before the "OnChanged" signal is evaluated, the limit checker does its work. So entering a value out of the limits does not trigger an OnChange event.

How is this with LCL?

In my case it is a motor control. With less than 0.1 % of it max. power, it doesn not spin, with negative values, it would spin in the other direction. Therefore I simply set the MinValue to "0.1". I wrote this software about 2 years ago and up to now it worked well - when you try to enter a zero or minus sign, you cannot do this and the onChanged event is not triggered - like it is with Qt.

So did I made a big mistake for a long time?
Suppose you have a procedure SpinMotor(Power: Double) which you call from the OnChange event of the SpinButton. You know that when SpinButton.Value is zero the procedure will crash. You prevent this you set the SpinButton.MinValue to 0.1 -- fine. But some time in the future you have a great idea and call SpinMotor from another place in your code, and the Power argument is provided from somewhere else which is not protected to become zero. Now you have that old problem again...

It is so easy to fix the issue without any requirements on TSpinEdit:

Code: Pascal  [Select][+][-]
  1. procedure SpinMotor(Power: Double);
  2. begin
  3.   if Power < 0.1 then begin
  4.     ShowMessage('Power too small to spin the motor.');
  5.     exit;
  6.   end;
  7.   // Now do the calculation which can NEVER get a Power = 0
  8.   // ...
  9. end;

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: TSpinEdit Min/Max behaviour
« Reply #36 on: January 04, 2022, 07:26:29 pm »

> * MaxValue=-10, Minvalue=10 --> ok, there is no error message, but also, there is no unlimited spinning: clicking the spin buttons makes the edit jump between -10 and 10 without the intermediate values.

Understandable as well because what else would you do if max < min is allowed?

Ok:
MinValue means: Minimal Value.
MaxValue means: Maximum Value.

MinValue = 10
MaxValue = -10

How can any number be <= -10 and at the same time >= 10?
It cannot be.


The behaviour of the control in this case is "undefined", as in: it is never described in the documentation (of Delphi) how it should behave.
The behaviour in Delphi is most likely a side effect of how it was implemented.
(Naïve approach: if Value<MinValue then Value:=MinValue; then followed by if Value>MaxValue then Value:=MaxValue. Mind you I never looked at the source code of Delphi's TSpinEdit.)
Most likely they never even considered a user causing this.

For the same reason ("undefined") our implementation is valid as well.
IMO it is a bit less moronic then Delphi's implementation.

Most users (like you) will never have MinValue>MaxValue and will never encouter our implementation, nor Delphi's one.
(When I implemented it this way, I did blackbox testing agains D3 and tried to think of weird situations and then stubled upon this.)
In both cases (Delphi as well as Lazarus) they will find out the control behaves not exactly as they intended.

There is no "proper" way to handle this situation.
Raising an exception? Now the programmer always has to first examine the value of both MinValue and MaxValue if he wants to change both.
Simply disallow it? Same problem.

If primitive types were nullable, Value could return Null.
That would at least make some sense of it all.
But since that is not the case, we must return an actual Double or Integer.

Bart

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: TSpinEdit Min/Max behaviour
« Reply #37 on: January 04, 2022, 07:30:16 pm »
PS. While "undefined" in practice means: "anything goes", since the behaviour when MaxValue<MinValue is described in comments in our sourcecode, the Lazaras behaviour can be considered our official (as in: "defined") behaviour.

Bart

Muso

  • Sr. Member
  • ****
  • Posts: 356
Re: TSpinEdit Min/Max behaviour
« Reply #38 on: January 04, 2022, 07:30:18 pm »
If that is not the case in QT, then this looks like a bug to me.

It is a feature since Qt 4.3:
https://doc.qt.io/qt-5/qabstractspinbox.html#keyboardTracking-prop

The content of the edit is first evaluated when you leave the edit and this way declare being ready. As you can see in the attached screencast where this feature is used that you cannot do anything wrong since the Qt limit and value checker does everything for you. In the screencast I first enter a minus sign that is directly blocked.

Muso

  • Sr. Member
  • ****
  • Posts: 356
Re: TSpinEdit Min/Max behaviour
« Reply #39 on: January 04, 2022, 07:31:56 pm »
Now you have that old problem again...
It is so easy to fix the issue without any requirements on TSpinEdit:

I understand now. Thanks.

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: TSpinEdit Min/Max behaviour
« Reply #40 on: January 04, 2022, 07:34:53 pm »
If that is not the case in QT, then this looks like a bug to me.

It is a feature since Qt 4.3:
https://doc.qt.io/qt-5/qabstractspinbox.html#keyboardTracking-prop

The content of the edit is first evaluated when you leave the edit and this way declare being ready. As you can see in the attached screencast where this feature is used that you cannot do anything wrong since the Qt limit and value checker does everything for you. In the screencast I first enter a minus sign that is directly blocked.

Yes, that is a nice feature that makes the control robust.
Kudo's to QT.

However, since T(Float)SpinEdit derives from TCustomEdit, the bevaiour you describe (no OnChange) is incompatible with how it is supposed to be in  LCL.
So, technically I think it is a bug (not in QT, but in our implementation in QT), but if I were a QT user, I would not want tha bug to be fixed...

Bart

Muso

  • Sr. Member
  • ****
  • Posts: 356
Re: TSpinEdit Min/Max behaviour
« Reply #41 on: January 04, 2022, 07:39:31 pm »
MinValue = 10
MaxValue = -10
How can any number be <= -10 and at the same time >= 10?
It cannot be.

Exactly and that is why I would not allow this. But as you stated it is **not** forbidden. Thus the UI must somehow allow this. Therefore I wrote, under these circumstances I don't have a better idea than what the Delphi guys implemented.

You know my opinion that I would change the IDE not to allow max < min.

We debated the pros and cons and I think you can make a decision on what the IDE should allow. If max < min should be allowed by the IDE, then Delphi's implementation makes sense to me.

However since I am an LCL newbie, you and wp should debate this and I should be quiet now   :-\.
« Last Edit: January 04, 2022, 07:54:23 pm by Muso »

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: TSpinEdit Min/Max behaviour
« Reply #42 on: January 04, 2022, 10:06:58 pm »
However since I am an LCL newbie, you and wp should debate this and I should be quiet now   :-\.

No, you should not be quite, at least not because you're a newbie and I'm not.
I welcome your input, even though we disagree.
This discussion gives us insight in what a common user expects and, just because of that, it's worthwhile.

Bart

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: TSpinEdit Min/Max behaviour
« Reply #43 on: January 04, 2022, 11:36:18 pm »
Been following this thread a bit..

Using Trunk on windows 10.

The FloatSpinEdit allows me to enter multiple ".", should that be happening ?


Also,
 
 Implementing the OnEditingDone I noticed that when using the keyboard any value I type in out of range will be corrected when hitting the enter key to fit the range however, it does not properly update the EDIT window to show the in range value that it just got changed to
, the out of range value which is incorrect is still showing.

 I did notice however if I move to another control using the Mouse and maybe the tab key it then updates.

Just something I noticed and yes I am sure it can be corrected in user code too but it just seems strange to me.
The only true wisdom is knowing you know nothing

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: TSpinEdit Min/Max behaviour
« Reply #44 on: January 04, 2022, 11:46:49 pm »
The FloatSpinEdit allows me to enter multiple ".", should that be happening ?

The code that does this actually only blocks keys that can never be allowed, e.g. 'a'.
The lagorithm to detect wether a dot is allowed might look straigh forward (only allow if it is not already there) , but then again, if I want to change 12.3 into 1.23 and I do so by first typing the '.' after the '1' and then proceed to delet the '.' after the '2', I cannot do so.
So, I considered the simple approach and rejected it.
(Notice that (on Windows at least) you can paste any amount of garbage into the control, so being too tight in rejecting key-input makes little sense.)

Implementing the OnEditingDone I noticed that when using the keyboard any value I type in out of range will be corrected when hitting the enter key to fit the range however, it does not properly update the EDIT window to show the in range value that it just got changed to
, the out of range value which is incorrect is still showing.

 I did notice however if I move to another control using the Mouse and maybe the tab key it then updates.

That doesn't sound quit allright to me...
I'll try to look into that.

However: this is off-topic to this thread.

Bart

 

TinyPortal © 2005-2018