Moving Low Level Graphics (GFX) Objects on your Charts

When drawing gfx objects on your charts, you can move them around by applying an X and Y offset to the coordinates of the object. The following code shows a simple example of how you can move a square object around your chart.

function DrawButtonTextx1y1x2y2BackColor )
{
    GfxSetOverlayMode);
    GfxSelectFont"Tahoma"12800 );
    GfxSelectPencolorBlack );
    GfxSetBkMode);
    GfxSelectSolidBrushBackColor );
    GfxSetBkColorBackColor );
    GfxSetTextColor);
    GfxRectanglex1y1x2y2 );
    GfxDrawTextTextx1y1x2y232 );
}
 
Yoffset Param"Button Row Offset (px)"5002000);
Xoffset    Param"Button Column Offset (px)"5002000);
CellHeight Param("Cell Height",20,5,200,5);   
CellWidth Param("Cell Width",120,5,200,5);  
DrawButton"TEST"XoffsetyoffsetXoffset CellWidthyOffset CellHeightcolorBlue );

If you only need to adjust the position of your object once in awhile, this simple method may serve best. However, when you want to move an object on the fly, without having to open the Param window each time, you can do this by registering the coordinates of your first click on the object and then move the object to the location of your next mouse click. The program below shows how to do this. It also shows you how to detect whether your click is within the object area (see the CursorInField variable).

To facilitate readability, the code has not been optimized. You can see in the captures below the code only adds about 4 microseconds to your execution time. It is doubtful that code optimization will have much effect on the overall execution time of your code. To test this code you Apply it to an indicator. At First Apply, it will display the Yellow Square with the word TEST in it:

clip_image002

When you click within the yellow square with your Left mouse button, it will turn Red:

clip_image004

The red color indicates that a move is in progress and that the next click will determine the location to which the object will be moved. After the move is completed, the object will return to its default yellow color:

clip_image006

In a real application, you may want to add some protective code that disables other mouse click activated actions while a move is in progress. Such code would be disabled while the object is Red and the variable MoveInProgress is true.

While the code could be (and initially was) written to move the object by holding down the Left Mouse button and dragging the object in the conventional way, the one-second minimum chart refresh rate makes this extremely awkward and slow to work with. For diagnostic purposes, a Reset button in provided in the Param window. Clicking this button will move the yellow square to its default coordinates.

function DrawButtonTextx1y1x2y2BackColor )
{
    GfxSetOverlayMode);
    GfxSelectFont"Tahoma"12800 );
    GfxSelectPencolorBlack );
    GfxSetBkMode);
    GfxSelectSolidBrushBackColor );
    GfxSetBkColorBackColor );
    GfxSetTextColor);
    GfxRectanglex1y1x2y2 );
    GfxDrawTextTextx1y1x2y232 );
}


ParamSqrSize    100;
Reset ParamTrigger"Reset Coordinates""RESET" );
xOffset  StaticVarGet"xOffset" );
YOffset  StaticVarGet"YOffset" );

if ( IsNullxOffset ) OR IsNullyOffset ) OR Reset )
{
    StaticVarSet"xOffset"20 );
    StaticVarSet"yOffset"20 );
    X1 XOffset;
    Y1 YOffset;
    X2 XOffset ParamSqrSize;
    Y2 YOffset ParamSqrSize;
    StaticVarSet"X1"X1 );
    StaticVarSet"X2"X2 );
    StaticVarSet"Y1"Y1 );
    StaticVarSet"Y2"Y2 );
    StaticVarSet"MoveinProgress"False );
}

X1 NzStaticVarGet"X1" ) );

X2 NzStaticVarGet"X2" ) );
Y1 NzStaticVarGet"Y1" ) );
Y2 NzStaticVarGet"Y2" ) );
LButtonTrigger    GetCursorMouseButtons() == 9;
MousePx  NzGetCursorXPosition) );
MousePy  NzGetCursorYPosition) );

CursorInField MousePx X1 AND MousePx X2 AND MousePy Y1 AND MousePy Y2;

MoveInProgress NzStaticVarGet"MoveInProgress" ) );

BackColor colorYellow;

if ( NOT MoveInProgress )
{
    if ( LButtonTrigger AND CursorInField )
    {
        StaticVarSet"BackColor"colorRed );
        StaticVarSet"DownPx1"MousePx );
        StaticVarSet"DownPy1"MousePy );
        StaticVarSet"MoveinProgress"True );

    }
}
else
    if ( LButtonTrigger )
    {
        StaticVarSet"BackColor"colorYellow );
        DownPx1 StaticVarGet"DownPx1" );
        DownPy1 StaticVarGet"DownPy1" );
        xMove MousePx DownPx1;
        yMove MousePy downPy1;
        PrevxOffset StaticVarGet"xOffset" );
        PrevYOffset StaticVarGet"YOffset" );
        xOffset PrevxOffset xMove;
        yOffset PrevYOffset yMove;
        StaticVarSet"xOffset"xOffset );
        StaticVarSet"yOffset"yOffset );
        StaticVarSet"MoveinProgress"False );
    }


BackColor NzStaticVarGet"BackColor" ), colorYellow );

xOffset StaticVarGet"xOffset" );
YOffset StaticVarGet"YOffset" );
X1 XOffset;
Y1 YOffset;
X2 XOffset ParamSqrSize;
Y2 YOffset ParamSqrSize;
StaticVarSet"X1"X1 );
StaticVarSet"X2"X2 );
StaticVarSet"Y1"Y1 );
StaticVarSet"Y2"Y2 );
DrawButton"TEST"x1y1x2y2BackColor );

Edited by Al Venosa.

Comments are closed.