Snap to ruler's divisions

Good day! Can you tell me please, how to implement so that when the position or size of the block changes by mouse (dynamically), the mouse cursor will automatically snap to the ruler's divisions? Simply put, implement a snap to current ruler grid.

I turned on SnapGrid — it works, but if the block has arbitrary position and/or size, then the cursor does not "hit" the ruler divisions. It hit only SnapGrid's SizeX, SizeY cells. TGridStyle=gsRuler does not solve the problem (


Use SnapToRuler property:

atDiagram1.SnapGrid.SnapToRuler := True;
1 Like

Thank you, Wagner! The issue was partially resolved, but not completely. When created, the blocks are placed exactly at the intersection of the grid (success), but snapping to the grid does not work:

  1. When the block size changes (screenshot snap2.png)
  2. When zooming (screenshot snap3.png)

Perhaps, after creation and after zooming, I need to somehow "fit" the position and/or size of the blocks?



I don't see such issue here. Please check the attached sample project. (7.4 KB)

Hi Wagner, in your example the issue also persists. I create simple rectangle — it creates always aligned to the grid (that's right), but rectangle has a default size. Because size of rectangle is default, its right or bottom edge(s) is not aligned to the grid. I am trying to resize the rectangle manually (with the mouse), but its only resizes at TSnapSize SizeX / SizeY intervals, and this intervals do not match the grid divisions (see screenshot). The idea of snapping to a grid doesn't work. I hope my question is clear)

I think recalculation of coordinates in the diagram when cursor position changes occurs from the current position through the SizeX / SizeY intervals, but it is probably more correct to snap to the nearest grid cross first, and then use SizeX / SizeY values.

That's by design. Once a block is inserted, it's resized by increments of the snap grid. If user inserts the block by dragging, the width and height will snap to grid. The situation you mentioned will only happen when the block is inserted through a click.

In this case, you can force the block right and bottom sides to be snapped to the grid by using the OnInsertDControl event:

procedure TForm5.atDiagram1InsertBlock(Sender: TObject;
  ABlock: TCustomDiagramBlock);
  P: TDot;
  P := atDiagram1.SnapDeltaPoint(ABlock.BoundsRect.BottomRight);
  ABlock.BoundsRect := Square(ABlock.Left, ABlock.Top, P.X, P.Y);
1 Like

Thanks a lot, Wagner! This is what I need)

1 Like

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.