Recent

Author Topic: Weird error: component not appearing where it should  (Read 1239 times)

heebiejeebies

  • Full Member
  • ***
  • Posts: 143
Weird error: component not appearing where it should
« on: March 23, 2025, 02:43:58 am »
Got a strange one. My UI is far too complicated to autoscale, so I've created 4 different resolutions, and in a separate unit I have a TStringGrid that contains all the scaling data. Component names go in the first column, and property names go in the top row. It handles height, width, left, top and some other special components like fonts and font sizes for Labels etc.  Here is the code that reads the scaling data, which worked perfectly up until today:

Code: Pascal  [Select][+][-]
  1. procedure TMainForm.ApplyScaling(Resolution: String);
  2. var
  3.   Grid: TStringGrid;
  4.   i, j: Integer;
  5.   CompName, PropName, PropValue: String;
  6.   Comp: TComponent;
  7.   PropInfo: PPropInfo;
  8.   ScreenWidth, ScreenHeight: Integer;
  9. begin
  10.   // Set MainForm size based on resolution
  11.   case Resolution of
  12.     '4K': begin ScreenWidth := 3200; ScreenHeight := 1750; end;
  13.     'HiRes': begin ScreenWidth := 2560; ScreenHeight := 1540; end;
  14.     'HD': begin ScreenWidth := 1920; ScreenHeight := 1050; end;
  15.     'LoRes': begin ScreenWidth := 1366; ScreenHeight := 738; end;
  16.   else
  17.     Exit; // Invalid resolution
  18.   end;
  19.  
  20.   MainForm.Width := ScreenWidth;
  21.   MainForm.Height := ScreenHeight;
  22.  
  23.   // Select the correct grid based on OS and resolution
  24.   case CurrentOS of
  25.     osWindows:
  26.       case Resolution of
  27.         '4K': Grid := ScalingData.WPanels4k;
  28.         'HiRes': Grid := ScalingData.WPanelsHiRes;
  29.         'HD': Grid := ScalingData.WPanelsHD;
  30.         'LoRes': Grid := ScalingData.WPanelsLoRes;
  31.       end;
  32.     osMacOS:
  33.       case Resolution of
  34.         '4K': Grid := ScalingData.MPanels4k;
  35.         'HiRes': Grid := ScalingData.MPanelsHiRes;
  36.         'HD': Grid := ScalingData.MPanelsHD;
  37.         'LoRes': Grid := ScalingData.MPanelsLoRes;
  38.       end;
  39.     osLinux:
  40.       case Resolution of
  41.         '4K': Grid := ScalingData.LPanels4k;
  42.         'HiRes': Grid := ScalingData.LPanelsHiRes;
  43.         'HD': Grid := ScalingData.LPanelsHD;
  44.         'LoRes': Grid := ScalingData.LPanelsLoRes;
  45.       end;
  46.   else
  47.     Exit; // Fail-safe
  48.   end;
  49.  
  50.   // Loop through each row (components)
  51.   for i := 1 to Grid.RowCount - 1 do
  52.   begin
  53.     CompName := Grid.Cells[0, i];  // Get component name from first column
  54.     Comp := MainForm.FindComponent(CompName);
  55.  
  56.     if Assigned(Comp) then
  57.     begin
  58.       // Loop through each column (properties)
  59.       for j := 1 to Grid.ColCount - 1 do
  60.       begin
  61.         PropName := Grid.Cells[j, 0];  // Property name from header row
  62.         PropValue := Grid.Cells[j, i]; // Value from grid
  63.  
  64.         // Skip the dummy "Type" column
  65.         if PropName = 'Type' then Continue;
  66.  
  67.         if (Comp is TBGRALabel) and (PropName = 'Font.Size') then
  68.        begin
  69.        TBGRALabel(Comp).Font.Size := StrToIntDef(PropValue, 0);
  70.        end;
  71.  
  72.          if (Comp is TBGRALabelFX) and (PropName = 'Font.Size') then
  73.        begin
  74.        TBGRALabelFX(Comp).Font.Size := StrToIntDef(PropValue, 0);
  75.        end;
  76.  
  77.          if (Comp is TBGRALabel) and (PropName = 'Font.Name') then
  78.        begin
  79.        TBGRALabel(Comp).Font.Name := PropValue;
  80.        end;
  81.  
  82.         if (Comp is TBGRALabelFX) and (PropName = 'Font.Name') then
  83.        begin
  84.        TBGRALabelFX(Comp).Font.Name := PropValue;
  85.        end;
  86.  
  87.         // Skip empty properties
  88.         if (PropValue <> '') then
  89.         begin
  90.           PropInfo := GetPropInfo(Comp.ClassInfo, PropName);
  91.           if Assigned(PropInfo) then
  92.           begin
  93.             // Convert and apply value
  94.             case PropInfo^.PropType^.Kind of
  95.               tkInteger, tkInt64:
  96.                 SetPropValue(Comp, PropName, StrToIntDef(PropValue, 0));
  97.               tkFloat:
  98.                 SetPropValue(Comp, PropName, StrToFloatDef(PropValue, 0.0));
  99.               tkString, tkLString, tkAString, tkWString, tkUString:
  100.                 SetPropValue(Comp, PropName, PropValue);
  101.             end;
  102.           end;
  103.         end;
  104.       end;
  105.     end;
  106.   end;
  107. end;      
  108.  
                                 

When I select High Resolution, everything scales perfectly except for one item - a TBCRoundedImage called MainHomeBtn1, which scales to the correct size but appears about 15 pixels too low on screen. I have other TBCRoundedImages that scale perfectly. The Top data in the string grid is definitely correct; there is definitely only one entry for this component in the grid and there is nothing else in code that changes its Top value. The weirdest part is, it only appears in the wrong position when you switch to High Resolution while the component is not on screen. If you have a different TabSheet active so that the component is invisible when the resolution switch happens then the error occurs. If it's on screen at the time, it appears in the correct position. This only happens once though, so if you change the resolution while it's on screen, then switch tabsheets and change resolution while it's off screen, it will not move to the wrong place.

Hardcoding instructions at the end of the ApplyScaling procedure does not help.

I understand this might be one of those "we can't help you unless you attach your entire project" situations, but I can't really do that. I'm hoping someone can at least point me in the right direction regarding workarounds, even if no-one can diagnose the issue.

Thanks for your time! :)
Mint 22 Cinnamon / FPC 3.3.1 / L 3.6.0

jamie

  • Hero Member
  • *****
  • Posts: 6869
Re: Weird error: component not appearing where it should
« Reply #1 on: March 23, 2025, 02:38:58 pm »
Make sure you dont have client align flag or anchors enabled for that componet if u r doing all of the layout yourself.
The only true wisdom is knowing you know nothing

heebiejeebies

  • Full Member
  • ***
  • Posts: 143
Re: Weird error: component not appearing where it should
« Reply #2 on: March 25, 2025, 03:22:17 am »
Thanks Jamie! No client align or anchors on that component  :(

This one really has me stumped. I have at least found a workaround, which is to add in a second entry for that component in the StringGrid, and alter its Top value by +15 pixels. Weirdly, this makes it appear in the correct place in all circumstances. But given I don't understand it, I'd rather not rely on it so if anyone has any ideas I'd appreciate them. Bring in an exorcist, maybe?
Mint 22 Cinnamon / FPC 3.3.1 / L 3.6.0

Zvoni

  • Hero Member
  • *****
  • Posts: 2961
Re: Weird error: component not appearing where it should
« Reply #3 on: March 25, 2025, 09:45:23 am »
Thanks Jamie! No client align or anchors on that component  :(

This one really has me stumped. I have at least found a workaround, which is to add in a second entry for that component in the StringGrid, and alter its Top value by +15 pixels. Weirdly, this makes it appear in the correct place in all circumstances. But given I don't understand it, I'd rather not rely on it so if anyone has any ideas I'd appreciate them. Bring in an exorcist, maybe?
Parent/Owner/Container to that Component is properly set (a TabSheet?)?
Maybe you just "think" it's on the TabSheet, when in reality it's on the Form
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

wp

  • Hero Member
  • *****
  • Posts: 12756
Re: Weird error: component not appearing where it should
« Reply #4 on: March 25, 2025, 10:22:28 am »
I see that you are doing your own scaling. In this case you must make sure that the box "Use LCL Scaling (High DPI)" in the project options is turned off. And also the Scaled property of the form should be turned off.

heebiejeebies

  • Full Member
  • ***
  • Posts: 143
Re: Weird error: component not appearing where it should
« Reply #5 on: March 26, 2025, 04:09:03 am »
Thanks everyone! I've turned off the Scaled property, turned off LCL Scaling (Hi DPI), confirmed that the button definitely has the right parent. The issue still persists.  :(  My workaround appears to be holding up for the Hi DPI scaling, but now I'm having similar issues with the Low DPI  version.  In Low DPI it's not even resizing the button, so it appears huge while every other component else scales correctly. Using the workaround (i.e. adding a duplicate entry to the scaling data StringGrid with slightly different values) doesn't seem to have any effect on Low DPI.

I even tried creating a new image/button to replace the problematic one, new component name and everything - but the same thing happens to the new button when it's placed in that position on the form.  Weirdest bug I've ever encountered for sure!  :(

So, do I need to completely throw this approach out and scale using a different method?
Mint 22 Cinnamon / FPC 3.3.1 / L 3.6.0

Thaddy

  • Hero Member
  • *****
  • Posts: 16781
  • Ceterum censeo Trump esse delendam
Re: Weird error: component not appearing where it should
« Reply #6 on: March 26, 2025, 12:22:55 pm »
You should have listened to wp: never try to do your own scaling, it clashes with the Lazarus provided scaling.
Changing servers. thaddy.com may be temporary unreachable but restored when the domain name transfer is done.

wp

  • Hero Member
  • *****
  • Posts: 12756
Re: Weird error: component not appearing where it should
« Reply #7 on: March 26, 2025, 12:52:04 pm »
Well, I didn't say that, but in essence Thaddy is right: The built-in LCLscaling is very reliable (you can see it at work in the IDE). If it is not working for you I'd dare to say that you are doing something wrong or are using non-scaling components.

You are mentioning TBCRoundedImage which is not an LCL component. Are you sure that it supports LCLScaling internally correctly? Just drop it on a form, adjust its size to be, say, one half of the form, compile (with LCLScaling enabled) and run the binary at various screen resolutions: It is expected that the size of the component always is one half of the form.

heebiejeebies

  • Full Member
  • ***
  • Posts: 143
Re: Weird error: component not appearing where it should
« Reply #8 on: March 26, 2025, 08:16:21 pm »
Thanks guys, appreciate the thoughts. Believe me, it cannot be done with auto-scaling. If it could, I'd save myself all this headache and extra work. e.g. Many of the screens contain lists of information split up into chunks - so on one screen I have 12 listboxes full of information, each with their own sidebar listbox to number each of the entries. Try auto scaling 24 listboxes and getting everything to line up and use a reasonable font size. Also some other screens have image diagrams that need to line up perfectly with other images beneath them. All of these things scale perfectly using my method - it's only the TBCRoundedImage that I'm having issues with, and again - only that one button. The other 7 or so TBCRoundedImage buttons on screen look just fine.

Anyway.......... My workaround for the moment is I've just added the ApplyScaling routine to the OnChange of the Tabsheet. This seems to work fine, at least for the moment. So unless anyone has a better idea, I guess this is it.
Mint 22 Cinnamon / FPC 3.3.1 / L 3.6.0

jamie

  • Hero Member
  • *****
  • Posts: 6869
Re: Weird error: component not appearing where it should
« Reply #9 on: March 26, 2025, 09:36:56 pm »
Screen shot ?
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 16781
  • Ceterum censeo Trump esse delendam
Re: Weird error: component not appearing where it should
« Reply #10 on: March 27, 2025, 10:47:09 am »
Now playing Oh Well, Fleetwood Mac
Changing servers. thaddy.com may be temporary unreachable but restored when the domain name transfer is done.

 

TinyPortal © 2005-2018