pcb-rnd knowledge pool
How actions shall query cursor/crosshair coordinates
action_coords by Tibor 'Igor2' Palinkas on 2018-06-15
Tags: dev, action, coordinates, coords, crosshair, mouse, pointer, cursor
Abstract: As of pcb-rnd r17330 (or release 2.0.1), the API for actions getting screen coordinates changed. This document is a summary on how to use the new API.
The two kind of screen coords
One pair of coordinates is where the (mouse) pointer is actually pointing to. This is called the ptr coord. The ptr coord ignores any grid and object snapping. The resolution is controlled by the zoom level only. The related fields are pcb_crosshair.ptr_x and pcb_crosshair.ptr_y.
The other pair of coordinates is the crosshair's position. Depending on user settings, the crosshair is usually adjusted to fit to the grid and/or snap to special points of visible objects. The related fields are pcb_crosshair.X and pcb_crosshair.Y.
All these coordinates are stored in board coordinates (pcb_coord_t). When the mouse cursor leaves the drawing area, the last value may be remembered (which may even be slightly off to the edge of the drawing area) or the values can be set to zero. There is no query to find out if the current values are valid in the sense that the crosshair is drawn and the pointer is within the drawing area. Instead, there is a way to enforce validity (which may require/enforce user interaction).
Requiring user interaction
Calling pcb_hid_get_coords() will update all the above coordinates in case the GUI is present (else it sets them to zero). If the pointer is within the drawing area by the time of the call, the existing coordinates are used. If it is not, the user is prompted with the string in the msg parameter and pcb-rnd requires a click to enter a new coordinate.
When to use which
Each case is unique, there is no generic rule that can blindly decide. There are a few conventions, tho. If an action needs an object to be selected, we tend to use the ptr coords so the user does not need to turn off the grid to reach small, off-grid objects. Drawing actions on the other hand use the crosshair coordinates letting the user utilize the grid/snapping mechanisms to achieve precise drawing.
Difference from the old API
The old API used to deliver the last seen x;y coordinates in case the pointer was in the drawing. Enforcing validity happened through configuration: while registering an action a "query coords" message could be specified; when present, core called pcb_hid_get_coords() before the action. This mechanism got removed, because:
- only a tiny minority of the actions relied on it
- reproducing the query in actions when needed is like 2 lines
- it didn't let actions differentiate whether they need a coordinate or not, so actions that had to make this decision on the fly had to do direct call anyway
- in return it made the API more complicated and verbose for the vast majority of actions that did not need this feature
- and made the API incompatible with fungw calling conventions