Recent

Author Topic: Form moving on resize  (Read 2266 times)

andyH

  • Jr. Member
  • **
  • Posts: 99
Form moving on resize
« on: May 09, 2021, 10:41:35 pm »
I have a simple form with a single button. That button launches another form with an image, label and a couple of buttons - a message form. Nothing special, but having problems with the message form when I resize it.

I have a resize function on the message function. It works, but as soon as I resize the form moves left and up. Move form back to the centre of the screen - resize and off it goes stage left and up to the top left of the screen again. The constructor has Position:= poScreenCenter (that works), I've put the same again in the resize function to no effect.

The resize function is
Code: Pascal  [Select][+][-]
  1. procedure TMyMsg.MsgResize(Sender : TObject);
  2. var
  3.   LineHeight, NoLines, NoLF : byte;
  4.   i : integer;
  5. begin
  6.   //message label
  7.   MsgLbl.Width:= Self.Width - fwImage - 3 * fwBorder;
  8.   LineHeight:= xGetTextHeight('Ag',MsgLbl.Font);
  9.   NoLF:= 0;
  10.   for i:= 1 to length(MsgLbl.Caption) do
  11.       if MsgLbl.Caption[i] = LineEnding then NoLf+= 1;
  12.   with MsgLbl do NoLines:= round(xGetTextWidth(Caption,Font)/Width + NoLF/2);
  13.   if NoLines <= 5 then NoLines+= 1; //by inspection was chopping off at the bottom
  14.   MsgLbl.Height:= NoLines * LineHeight;
  15.   //Buttons
  16.   Btn1.BorderSpacing.left:= Self.Width - fwBorder - Btn1.Width;
  17.   Btn2.BorderSpacing.left:= Self.Width - 2 * fhBorder - Btn2.Width - Btn1.Width;
  18.   Self.Height:= fhBorder * 2 + MsgLbl.Height + Btn1.Height;
  19.   Self.Position:= poScreenCenter;
  20. end;
Doesn't do much more than re-calculate width/height of the tlabel and reset the border spacing on the buttons.

The form gets created as
Code: Pascal  [Select][+][-]
  1.  MsgForm:= TMyMsg.CreateNew(nil);

Why does it keep wandering around the screen on resize. I have another 'pop up' form that does not exhibit this behaviour on resizing?

Running under linux (linux mint).

First screenshot - as created and sat in the middle of the screen, second - after resize but form is now in the top left hand corner of the screen.


« Last Edit: May 09, 2021, 10:43:55 pm by andyH »

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: Form moving on resize
« Reply #1 on: May 10, 2021, 03:39:46 am »
What widget set are you using?

andyH

  • Jr. Member
  • **
  • Posts: 99
Re: Form moving on resize
« Reply #2 on: May 10, 2021, 08:54:50 am »
GTK under linux

andyH

  • Jr. Member
  • **
  • Posts: 99
Re: Form moving on resize
« Reply #3 on: May 10, 2021, 04:40:44 pm »
Done a bit more troubleshooting but no closer to a workable solution.

Adding to the constructor:
Code: Pascal  [Select][+][-]
  1. Position:= poScreenCenter;
  2. writeln('constructor, top=',top,' left=',left);
and then adding
Code: Pascal  [Select][+][-]
  1. writeln('resize top=',self.top,'   left=',self.left);
to the resize function results in:

Code: Pascal  [Select][+][-]
  1. constructor, top=0 left=0
  2. resize top=0   left=0
  3. resize top=390   left=1120
  4. resize top=390   left=1120
  5. resize top=390   left=1120
  6. resize top=390   left=1120
  7. resize top=358   left=1080
  8. resize top=358   left=1080
  9. resize top=358   left=1080
  10. resize top=358   left=1080
  11. resize top=342   left=1060
  12. resize top=342   left=1060
  13. resize top=310   left=1020
  14. resize top=310   left=1020
  15. resize top=310   left=1020
  16. resize top=310   left=1020
  17. resize top=294   left=1000
  18. resize top=294   left=1000
  19. resize top=262   left=960
  20. resize top=262   left=960
  21. resize top=246   left=940
  22. resize top=246   left=940
clearly using poScreenCenter does not assign any values to left or top, but you can see the form moving towards the top left of the screen (0,0) as it is resized. As soon as you resize (X,Y) values are assigned (so why not with poScreenCenter?).

replacing poScreenCenter with
Code: Pascal  [Select][+][-]
  1. left:= 400;
  2. top:= 400;
in the constructor results in:
Code: Pascal  [Select][+][-]
  1. constructor, top=400 left=400
  2. resize top=400   left=400
  3. resize top=400   left=400
  4. resize top=400   left=400
  5. resize top=400   left=400
  6. resize top=400   left=400
  7. resize top=400   left=400
  8. resize top=400   left=400
  9. resize top=400   left=400
  10. resize top=368   left=360
  11. resize top=368   left=360
  12. resize top=352   left=340
  13. resize top=352   left=340
  14. resize top=352   left=340
  15. resize top=352   left=340
  16. resize top=352   left=340
  17. resize top=320   left=300
  18. resize top=320   left=300
  19. resize top=304   left=280
  20. resize top=304   left=280
  21. resize top=288   left=260
  22. resize top=288   left=260
same as before, but the form is initially positioned at (400,400) and resizing rapidly moving it towards (0,0).

Adding
Code: Pascal  [Select][+][-]
  1. self.top:= 400;
  2. self.left:= 400;
to the resize function, produces the desired end result but in an undesired fashion.

As the form is resized by dragging the mouse it is visually moving towards (0,0). When the mouse is released the form snaps to the desired position at (400,400). If this is an improvement, it is a very small improvement. Would be disconcerting to an end user.

I'm a little further forward but would appreciate some suggestions:
  • how to calculate top left on the message form (X,Y) as poScreenCenter doesn't result in any values?
  • what is causing the problem in the first place - so when you resize the form (X,Y) remains unchanged?

The form moves top left as soon as you start to drag the size with the mouse. Is this a bug in the GTK implementation?

Would welcome any ideas on things to try.  :(

To add to my previous, running linux mint 20.1 with lazarus 2.0.10.

wp

  • Hero Member
  • *****
  • Posts: 11857
Re: Form moving on resize
« Reply #4 on: May 10, 2021, 05:30:59 pm »
Code: Pascal  [Select][+][-]
  1. procedure TMyMsg.MsgResize(Sender : TObject);
  2. begin
  3.   ...
  4.   Self.Height:= fhBorder * 2 + MsgLbl.Height + Btn1.Height;
  5. end;
Changing the Height inside the OnResize event looks wrong to me since this will trigger another OnResize. Please comment this line and check whether it has an effect on your observations.

andyH

  • Jr. Member
  • **
  • Posts: 99
Re: Form moving on resize
« Reply #5 on: May 10, 2021, 10:46:08 pm »
wp, many thanks. IT WORKED!

It would have taken me a long time to stumble on that, maybe never. Just another small step down my Lazarus learning curve. :D

 

TinyPortal © 2005-2018