View Issue Details

IDProjectCategoryView StatusLast Update
0018579LazarusIDEpublic2014-04-14 22:23
ReporterZex Atilla Assigned ToMattias Gaertner  
Status resolvedResolutionfixed 
Product Version0.9.29 (SVN) 
Summary0018579: Snap to grid doesn't work inside a group box
DescriptionInside a TGroupBox the controls in the Form Editor are aligned in an erratic and unpredictable way.
Additional InformationHow to reproduce:

1. Open Environment => Options => Form Editor
2. Turn on "Snap To Grid" and set grid to 10x10 (easier to check)
3. Create a new form
4. Add a TGroupBox
5. Put some controls inside TGroupBox and move them around

They aren't aligned to the 10x10 grid (or any other, regardless).
Tagscontrols, editor, form, grid, move, snap
Fixed in Revision44733
Attached Files


related to 0026023 new Locking controls in Form Designer (feature request) 


Zex Atilla

2011-02-10 17:47

reporter   ~0045938

Last edited: 2011-02-10 17:47

The same problem exists in TPageControl / TTabSheet

Zex Atilla

2011-02-15 16:30

reporter   ~0046075

This is actually a big pain in the butt when it comes to visual programming.

Every movement (even accidental) of a control makes it out of the grid. It would really help if the controls could be locked on the form, so they can't be moved unless they are explicitly unlocked.

Zex Atilla

2011-07-27 18:35

reporter   ~0050214

I still didn't find the source of this problem. But I have optimized a few Form Designer functions while chasing the bug. They are now simpler, easier for maintenance and probably a tiny bit faster (see bottom of this text).

It's interesting that anything inside a TPanel is aligned ok, while anything inside a TGroupBox/TPageControl has an irritating offset. My assumption is that Lazarus ignores the borders and title bars, so SnapToGrid doesn't work inside any controls that have ClientSize different than overall size. Now, how to fix that?

 file "ControlSelection.pp"

 Below are simplified and optimized functions

procedure TControlSelection.FindNearestGridX(var NearestInt: TNearestInt);
var GridSizeX, NearestGridX: integer;
  if not EnvironmentOptions.SnapToGrid then exit;
  NearestGridX := ((NearestInt.Level + GridSizeX div 2) div GridSizeX) * GridSizeX;

procedure TControlSelection.FindNearestGridY(var NearestInt: TNearestInt);
var GridSizeY, NearestGridY: integer;
  if not EnvironmentOptions.SnapToGrid then exit;
  NearestGridY := ((NearestInt.Level + GridSizeY div 2) div GridSizeY) * GridSizeY;

procedure TControlSelection.FindNearestClientLeftRight(
  var NearestInt: TNearestInt);
var MaxDist: integer;
  MaxDist:=(CleanGridSizeX+1) div 2;
  if NearestInt.Level<MaxDist then
  if (FForm<>nil)
  and (Abs(NearestInt.Level-FForm.ClientWidth)<MaxDist) then

procedure TControlSelection.FindNearestClientTopBottom(
  var NearestInt: TNearestInt);
var MaxDist: integer;
  MaxDist:=(CleanGridSizeY+1) div 2;
  if NearestInt.Level<MaxDist then
  if (FForm<>nil)
  and (Abs(NearestInt.Level-FForm.ClientHeight)<MaxDist) then

Juha Manninen

2012-10-13 11:15

developer   ~0063116

I committed your optimized methods. They seem to work. Thanks.
I don't know how to fix the actual issue.

Zex Atilla

2012-10-26 18:44

reporter   ~0063475

I have found the source of problem. Make this experiment: put an EditBox inside a GroupBox. Now move EditBox vertically upwards until it reaches topmost position, covering the GroupBox name. The EditBox must be fully visible. Now look at EditBox.Top coordinate. You would expect Top=0, but no, Top=-16. This 16-pixel vertical offset causes snapping errors.

Now I remember something related, when I was moving my forms from Delphi to Lazarus. After form conversion the contents of all TGroupBox controls was shifted to the down and right. TGroupBox in Lazarus has invalid client origin.

One solution is to fix GroupBox's client origin. But that's a breaking change, it would change the looks of all existing Lazarus programs.

Another solution is to change the Form Designer's snap-to-grid code to use local position. So it would snap all controls inside TGroupBox (or other container) using the local coordinate space of that container. Currently it uses Form's coordinate space.

Now we need someone familiar with MoveSelectionWithSnapping method located in ControlSelection.pp to make the change.

It should find the parent (or container) of the control being dragged. Then it should translate mouse coordinates from Form space to local parent space. Then snap those coordinates to grid. Then translate snapped coordinates back from container space to Form space.

If I catch time I may try changing that, but I'm not that familiar with Designer's code to be sure about success.

Zex Atilla

2014-04-14 19:22

reporter   ~0074395

Anyone knows how to fix this?

It's NOT a minor graphical glitch. It affects how controls are positioned, spacing between them and makes designing hard and time-consuming. That is, if one wants to stick to some design standards instead of just throwing controls anywhere on the form.

This is a pretty big bug that causes a lot more time to be spent during design. Sometimes it seems a lot easier to instantiate controls at run time to avoid this bug.

Zeljan Rikalo

2014-04-14 20:21

developer   ~0074397

I'm not so familiar with IDE designer code, but somewhere is missing offset of TGroupBox,TPageControl and others which can have offset (if everything is fine with TForm and TPanel). Maybe Mattias or Paul can help here.

Issue History

Date Modified Username Field Change
2011-01-21 20:04 Zex Atilla New Issue
2011-01-21 20:04 Zex Atilla Widgetset => Win32/Win64
2011-01-27 17:51 Zex Atilla Tag Attached: grid
2011-01-27 17:51 Zex Atilla Tag Attached: controls
2011-01-27 17:51 Zex Atilla Tag Attached: editor
2011-01-27 17:51 Zex Atilla Tag Attached: form
2011-01-27 17:51 Zex Atilla Tag Attached: forms
2011-01-27 17:51 Zex Atilla Tag Attached: move
2011-01-27 17:51 Zex Atilla Tag Attached: snap
2011-02-08 14:34 Vincent Snijders Tag Detached: forms
2011-02-08 14:34 Vincent Snijders LazTarget => -
2011-02-08 14:34 Vincent Snijders Status new => acknowledged
2011-02-10 17:47 Zex Atilla Note Added: 0045938
2011-02-10 17:47 Zex Atilla Note Edited: 0045938
2011-02-15 16:30 Zex Atilla Note Added: 0046075
2011-07-27 18:35 Zex Atilla Note Added: 0050214
2012-10-13 11:15 Juha Manninen Note Added: 0063116
2012-10-26 18:44 Zex Atilla Note Added: 0063475
2014-04-14 19:22 Zex Atilla Note Added: 0074395
2014-04-14 20:21 Zeljan Rikalo Note Added: 0074397
2014-04-14 20:22 Zeljan Rikalo Relationship added related to 0026023
2014-04-14 22:23 Mattias Gaertner Fixed in Revision => 44733
2014-04-14 22:23 Mattias Gaertner Status acknowledged => resolved
2014-04-14 22:23 Mattias Gaertner Resolution open => fixed
2014-04-14 22:23 Mattias Gaertner Assigned To => Mattias Gaertner