Recent

Author Topic: Default Component Size might not be working as expected  (Read 1032 times)

SandyG

  • Full Member
  • ***
  • Posts: 106
Default Component Size might not be working as expected
« on: April 12, 2025, 08:01:52 am »
Ran into something odd when creating a component.

I do the common override and it kinda' works but the default sized when the component is dropped on a form. When I set a default size for the component (by overriding) I get a component that is not that size, but larger. Change the values does change the default size so I know the code is getting called at design time, just not the expected size (Width and Height).
 
Code: Pascal  [Select][+][-]
  1. class function TBGRACustomSpinner.GetControlClassDefaultSize: TSize;
  2. begin
  3.   Result.CX := 100;
  4.   Result.CY := 100;
  5. end;
  6. ...
  7. // and in the constructor
  8.  
  9. ...
  10.   with GetControlClassDefaultSize do
  11.     SetInitialBounds(0, 0, CX, CY);
  12. ...
  13.  

Above code works but sizes don't match when you drop the component on a form. For the above code I get a component of Width and Height of 150 when the defaults are CX=CY=100. If I change the above code to make both 75 for CX and CY I get a component of 113 Width and Height.

The code is definitely doing something but not sure why the component size is not as specified in the GetControlClassDefaultSize or Should it be? Screen Resolution at play?

Sandy

jamie

  • Hero Member
  • *****
  • Posts: 6888
Re: Default Component Size might not be working as expected
« Reply #1 on: April 12, 2025, 12:08:33 pm »
Do u have scaled enable and your desktop is set to 150% ppi ?
The only true wisdom is knowing you know nothing

SandyG

  • Full Member
  • ***
  • Posts: 106
Re: Default Component Size might not be working as expected
« Reply #2 on: April 14, 2025, 03:01:11 am »
Yes, running on windows with a 4k screen at 150%.

I do see in Control.inc that GetDefaultWidth() and GetDefaultHeigh() both scale based CX and CY on the font size and are likely what I'm seeing when the component is dropped on the form.

So the question is, what is a good way to set the exact pixel size of a component for design time?

The issue is that other aspects of the component (It's a BGRABitmap based control) are based on the Default size of the component. So other default properties and aspects of the rendering are all based on a specific pixel size.

In experimenting with Windows scaling, if I am at 150% scaling, and my CX and CY values are both 100, then when I drop onto a form in design time it looks good as the Width and Height are set to 150px.

BUT

If shut down Lazarus and change windows scaling to 100% and restart, drop the component on the form, it's default Width and Height are 75, which is bad.

Bottom line is I want to control the components Width and Height and NOT have the design time use the scaled values LCL is coming up with. My guess it's easy, but I have no clue how to do this properly within the bounds of the component framework.

Any clues or directions to look (examples are super helpful)

Thanks

Sandy


SandyG

  • Full Member
  • ***
  • Posts: 106
Re: Default Component Size might not be working as expected
« Reply #3 on: April 17, 2025, 03:14:24 am »
Scaling in general is the culprit here.

Found this as a clue - https://forum.lazarus.freepascal.org/index.php/topic,63585.msg481807.html#msg481807

So the issue is that if the form is set to Scaled := True; all sorts of odd things can happen related to scaling. So not sure what the normal application practices are for scaling.

Also the in the designer mode when flipping Windows scaling from 100 to 150% (restarting lazarus each time), if the component sizes of 150wx150h existed when entering a scaled 100% desktop seems the lazarus designer will take it upon itself to scale the form at the 100% size in my case the component will be changed from 150x150x to 100x100. Odd.

Bottom line is going to change the default values to be visually usable at either Desktop Scaling setting and it's up to the end user to deal with 'To Scale or Not To Scale"

I should say these are more graphically styled components and likely need to be tested at various scaling on your desktop. More to learn...

I will leave this open if anyone has comments on scaling for a bit, then mark solved...

Sandy
« Last Edit: April 17, 2025, 03:18:13 am by SandyG »

wp

  • Hero Member
  • *****
  • Posts: 12792
Re: Default Component Size might not be working as expected
« Reply #4 on: April 17, 2025, 12:41:25 pm »
The issue is that other aspects of the component (It's a BGRABitmap based control) are based on the Default size of the component. So other default properties and aspects of the rendering are all based on a specific pixel size.
I do not understand why this is important to you, I even think that this is a wrong concept. What will you do when the user changes the size of the component? I think in any case your component must be prepared for this, and in this sense it is not relevant what the default size is. Your component must be designed relative to the current size rather than to the default size.

SandyG

  • Full Member
  • ***
  • Posts: 106
Re: Default Component Size might not be working as expected
« Reply #5 on: April 17, 2025, 07:57:13 pm »
In general I do agree sizes of components should scale as needed. However as the components I'm working on are very visual and are really down to the 1px for looking correct it is nice to have the ability to design by pixel and have it be as they say pixel perfect.

Many components just work OK when the scaling is enable, some don't.

And the issue I'm having is not with the designer of a form using the components and setting them up, it with the initial drag onto a form. The defaults values for many things are again, pixel perfect and would not lend well to bulk scaling as I have found in when trying to get the BGRASuperGauge to scale automatically. In addition their is a lot of default properties for these components and would be a large task to make them all work in concert. If everything visually scaled linearly it would be easy. A good example is fonts, small pixel dimension lines and borders, etc. It just looks odd when scaled.

On the BGRASuperGauge I have a check box for allow auto scale, which I attempted to start making it happen, but even with the fonts on the scale of the gauge it required several break points as it scaled and just looked off to make things fit and yet be readable (as an example), lots of ugly arbitrary code and hard to test. So their is a definite trade off in trying to do the auto scale vs. manual with fidelity.

I don't know how QT/GTK/etc. deal with it, but in Windows it seems odd when the display is scaled. Works for the most part but when a form is scaled and thus the components sizes are changed this doesn't necessarily work out at all for complex visual components. The nice thing is that the designers of Lazarus does give the option of the form to NOT SCALE and that works out fine for the situations where a fixed screen size is the planned target.

I'm still learning the ropes with component creation and Ideally it would be great to have auto scale and good visual fidelity, I think that might be a longer term target, but I'm not quite there yet, just want it to drop on a low or high dpi form in the designer and still look OK, then let the user change as needed.

It is a problem as I have seen in others post going from Design in HiDPI monitor to normal and the other way, and really wasn't aware until I started doing more testing. Again learning as I'm going!

Thanks for the feed back as it does press me to do more of the auto scale sizing as it seems it is needed.

Sandy


wp

  • Hero Member
  • *****
  • Posts: 12792
Re: Default Component Size might not be working as expected
« Reply #6 on: April 17, 2025, 08:03:47 pm »
To my knowledge, all the LCLScaling happens in AutoAdjustLayout inherited from TControl. It is a virtual method. So, if you want to disable scaling for this particular control, maybe you should override the method with empty code?
Code: Pascal  [Select][+][-]
  1. procedure TMyNonscalingControl.AutoAdjustLayout(AMode: TLayoutAdjustmentPolicy;
  2.   const AFromPPI, AToPPI, AOldFormWidth, ANewFormWidth: Integer);   // "override" in declaration
  3. begin
  4. end;
  5.  

But be warned: This component designed at 96ppi will hardly be distinguishable at 300ppi.
« Last Edit: April 17, 2025, 08:10:04 pm by wp »

SandyG

  • Full Member
  • ***
  • Posts: 106
Re: Default Component Size might not be working as expected
« Reply #7 on: April 17, 2025, 08:22:50 pm »
I had looked at that and tried messing with the ShouldAutoAdjust() options and could not make it work. Auto Scale and AutoLayout seem a bit different but have some overlapping. I started getting too deep into the Controls.inc and got lost  :)

Finally spotting the forms Scaled Option and setting it to false is likely the plan when using these graphic heavy components until I can sort out better scaling within the components. They are just really tricky to get right as it is, and then with any size scaling, it makes them less then nice.

Also just spotted in Lazarus the 'Force DPI Scaling in Design Time' I have no idea what that will do, but need to take a look. More options...

Thanks!

Sandy


wp

  • Hero Member
  • *****
  • Posts: 12792
Re: Default Component Size might not be working as expected
« Reply #8 on: April 18, 2025, 01:14:36 am »
In addition to AutoAdjustLayout care must also be taken that the size does not change when the control is dropped on the form at designtime - as was reported in the initial post. There is a simple solution for it: Make the control autosized. In this case the size of the control is defined by the virtual method CalculatePreferredSize, but no further scaling is applied later.

In the attachment you can find a simple component, TNonScalingControl, which is written such that its size is always 100x100, independently of scaling. (It is drawn as a white rectangle with red 1px-border, just to have something on the screen). To test it, install a package "noscaling_pkg" first. "demo_96ppi" was written at 96ppi - no matter whether you compile and run it at 96ppi or any other resolution, the control will always be 100x100 (click on Button1 to confirm). "demo_144ppi" was written at 144ppi - again the size of the control is always 100x100. Button2 in both demos creates a NonScalingControl at runtime, again it is 100x100 by default at any resolution.

SandyG

  • Full Member
  • ***
  • Posts: 106
Re: Default Component Size might not be working as expected
« Reply #9 on: April 18, 2025, 04:47:08 am »
Will take a look.

To be clear the size doesn't change by my code, it changes depending on if Windows scaling is at play on the 4k monitor at 150% or if Lazarus is run at scaling 100% and reopen the form for editing, then the values of Width and Height get changed by Lazarus when opening in the editor. OR if the test app is run in different scaling modes on Windows.

Just fixed another issue on sizing, which was an easy one for a change...

Eventually I'll figure it out ;)

Again thanks for the samples will get a look at it in the next few days and comment.

Sandy

 

TinyPortal © 2005-2018