OK, here we go.
PixInsight doesn't update dynamically generated graphics automatically. That's the sole responsibility of the dynamic interface.
In your DynamicPaint routine, you must be prepared to update your line if the passed update rectangle intersects it. For example:
bool MyInterface::RequiresDynamicUpdate( const View& v, const DRect& updateRect ) const
{
// myView is a View* that is the view where you're working (you normally
// have fetched it upon a DynamicMousePress() call, when a new dynamic
// session started. myView should be zero if no dynamic session is taking
// place (for safety).
// myRect is a DRect object that defines the current boundaries of your
// drawing in image coordinates.
return myView != 0 && v == *myView && myRect.Intersects( updateRect );
}
void MyInterface::DynamicPaint( const View& v, Graphics& g, const DRect& updateRect ) const
{
// Perform the drawing work. If possible, restrict and/or optimize your painting
// routine to draw only into the updateRect rectangle.
}
Bear in mind that the passed updateRect objects are in image coordinates. Image coordinates are always real numbers (of double type). Take into account also that the updateRect can define coordinates outside the image in the passed view v. This may happen if for example the user has zoomed out the image so it doesn't cover the current v's viewport.
Also take into account that these functions will be called very frequently. For example, as soon as the user moves the cursor over a view, PI will call your routines. First it will call your RequiresDynamicUpdate(). If that routine returns false, your DynamicPaint() won't be called. This greatly improves efficiency.
Finally, as you see, in PixInsight *all* drawing must take place inside paint event handlers. No drawing is possible if it has not been solicited explicitly by the core application. This is essential to ensure portability across platforms.