General Screen Reader by Graph Object

Version Info

Minimum Origin Version Required: Origin 8 SR6

Remark

This example is using Graph Object, including rectangle and crossing lines, to make a screen reader. After activate this rectangle, can move it by top, left... key to the exact position.

Need to Do Before Running Examples

Prior to running the following example, the grobj_utils.c file need to be loaded and compiled. This can be done from script with the following command or just add this file to your workspace.

run.LoadOC(Originlab\grobj_utils.c);

Example

#include <..\Originlab\grobj_utils.h>
#define STR_LINE_1_NAME   "MyLine1"
#define STR_LINE_2_NAME   "MyLine2"
 
#pragma labtalk(1)//To control the calling of Origin C function, for any LT usage, no need to be inside run command
 
// this function used to add rectangle and line on the active layer
void AddRectAndLine()
{   
    GraphLayer gl = Project.ActiveLayer();  // get active graph layer
 
    if( gl )    // if layer exist
    {    
        GraphObject goRect = gl.CreateGraphObject(GROT_RECT); 
        SetRectangleFormat(goRect, gl);
        
        GraphObject goVLine;    // vertical line
        GraphObject goHLine;    // horizontal line
        
        double dVLineX0, dVLineX1, dVLineY0, dVLineY1;  // coordinates of start and end points of vertical line
        dVLineX0 = goRect.X;                  // start point x0
        dVLineX1 = goRect.X;                  // end point x1
        dVLineY0 = goRect.Y - goRect.DY / 2.0;   // start point y0
        dVLineY1 = goRect.Y + goRect.DY / 2.0;   // end point y1
 
        // add vertical line    
        if( add_line(gl, goVLine, dVLineX0, dVLineY0, ATTACH_TO_SCALE, LN_FREE, false, false, dVLineX1, dVLineY1, SYSCOLOR_RED, STR_LINE_1_NAME) )  // add vertical line successfully
        {
            // set line format
            SetLineFormat(goVLine, goRect);
        }
 
        // coordinates of start and end points of horizontal line
        double dHLineX0, dHLineX1, dHLineY0, dHLineY1;
        dHLineX0 = goRect.X - goRect.DX / 2.0;    // start point x0
        dHLineX1 = goRect.X + goRect.DX / 2.0;    // end point x1
        dHLineY0 = goRect.Y;                   // start point y0
        dHLineY1 = goRect.Y;                   // end point y1
        
        // add horizontal line      
        if( add_line(gl, goHLine, dHLineX0, dHLineY0, ATTACH_TO_SCALE, LN_FREE, false, false, dHLineX1, dHLineY1, SYSCOLOR_RED, STR_LINE_2_NAME) )  // add horizontal line successfully
        {
            // set line format
            SetLineFormat(goHLine, goRect);
        }   
    }
}

// set rectangle object properties
void SetRectangleFormat(GraphObject& goRect, GraphLayer& gl)
{   
    if( gl )
    {
        // set size, position, color, etc. for rectangle.
        Tree tr;   
        tr.Root.Dimension.Units.nVal = UNITS_SCALE;
        tr.Root.Dimension.Attachment.nVal = 2;  // 2, attach layer and scale
        tr.Root.Dimension.Left.dVal = gl.X.From;    // left axis
        tr.Root.Dimension.Top.dVal = gl.Y.From;   // top axis
        tr.Root.Dimension.Width.dVal = (gl.X.To - gl.X.From) * 0.08;
        tr.Root.Dimension.Height.dVal = (gl.Y.To - gl.Y.From) * 0.1;
        
        tr.Root.Border.Color.nVal = SYSCOLOR_GRAY;
        tr.Root.Border.Width.nVal = 1;        
        tr.Root.Fill.Color.dVal = SYSCOLOR_LTGRAY; 
        
        tr.Root.KeepInside.nVal = true;   // keep this object always inside the graph layer
        tr.Root.BehindData.nVal = true;   // set rectangle behind data
        
        tr.Root.Event.nVal = GRCT_MOVE;   // event: move
        tr.Root.Script.strVal = "Run -OC MoveLines(this.Name$)";     // when move rectangle, call MoveLines()
        
        if(0 == goRect.UpdateThemeIDs(tr.Root))   // 0 means no error
        {
            bool bRet = goRect.ApplyFormat(tr, true, true);
            ASSERT(bRet);
        }        
        
        // to disable resize, rotate... after perpare size, postion.
        Tree tr1;        
        tr1.Root.States.dVal = GOC_NO_RESIZE|GOC_NO_ROTATE|GOC_NO_SKEW|GOC_HITTEST_BEFORE_DATA;
        
        if(0 == goRect.UpdateThemeIDs(tr1.Root))    // 0 means no error
        {
            bool bRet = goRect.ApplyFormat(tr1, true, true);
            ASSERT(bRet);
        }
    }
}

// set line object properties
void SetLineFormat(GraphObject& goLine, GraphObject& goRect)
{ 
        // to disable selectable, resize, rotate...     
    Tree tr; 
    tr.Root.States.dVal = GOC_NO_RESIZE|GOC_NO_ROTATE|GOC_NO_SKEW|GOC_NO_EDIT|GOC_NO_IN_PLACE_EDIT|GOC_NO_BORDERSIZE|GOC_NO_SELECT|GOC_NO_DEL_SEL_PT;
 
    if( 0 == goLine.UpdateThemeIDs(tr.Root) ) // 0 means no error
    {
        bool bRet = goLine.ApplyFormat(tr, true, true); // return true if applied format successfully
    }
    
    // make line to connect to rectange
    connect_justify(goRect, goLine, CTP_AUTO);
}
 
#pragma labtalk(2) //To control the calling of Origin C function, cannot use like LT command, only use in run -oc cmd
 
// call this function when rectangle moves
void MoveLines(string strRectName)
{  
    GraphLayer gl = Project.ActiveLayer();   // get the active layer
    
    if( !gl )   // if active layer not exist, return
        return;
    
    GraphObject goRect = gl.GraphObjects(strRectName);
    
    // print the center coordinate of the rectangle
    printf("X = %f \nY = %f\n", goRect.X, goRect.Y);
}