It seems to me that it is so clear in this codes, that nothing to comment. Just few word “how-to”: simply include this file into your source code and use clear and meaningful text (I put difference example at the bottom of this page)

ATSGUI.h

#include "sierrachart.h"
// #include "ATSGUI.h" 

// Write formatted text to SC system log
#define UI_Log(fmtstr, ...) { SCString t; t.Format(fmtstr, ##__VA_ARGS__); scptr->AddMessageToLog(t, 0); }

/* --- COMMON PARAMETERS ---
All defines contains common parameters stored into s_UseTool structure:
t - s_UseTool variable name. Can be used in this defines and directly in pure source code
x, y - coordinates (in %) started (0,0) in lower left corner. upper right corner have (100, 100)
b, tm - x-coordinates on chart (usualy t.Begin(End)Index and t.Begin(End)DateTime)
p - y-coordinates on chart (t.Begin(End)Value)
bs, tms, ps, be, tme, pe - corresponding coordinates of [s]tart and [e]nd points

color - color of single element (t.Color)
foreColor, backColor - text colors (t.Color, t.FontBackColor). if backColor < 0 - transparent background will be used
borderColor, fillColor - rectangle box colors
undergraph - 1-draw tool under main chart, 0-draw tool over chart (tool will cover chart)

Other parameters have meaningful names (like fontSize, fontName, type, style, width, ...)
*/


//———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
// GLOBALS
//———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
s_sc *scptr;

// to clear all drawing - remove all objects from LineNumberStart to LineNumber
int LineNumberStart = 100000;
int LineNumber = LineNumberStart;

#define COLOR_TRANSPARENT -1 


//———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
// INITIALIZATION
//———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
// UI_INIT MUST BE PLACED INSIDE MAIN FUNCTION "SCSFExport scsf_StudyName(SCStudyGraphRef sc) {" 
// TO CORRECTLY PROVIDE STATIC UNIQUE LineNumber SEQUENCE. 
//   init  - is starting number for LineNumber sequence
//   scptr - pointer no main SCStudyGraphRef sc
#define UI_INIT(init, sc) { LineNumber = (init); scptr = &sc; }


//———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
// CREATING NEW OBJECTS
//———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
#define UI_NewText(t) \
	s_UseTool t; t.Clear();  \
	t.LineNumber = ++LineNumber; t.UseRelativeVerticalValues = 0; t.AddMethod = UTAM_ADD_OR_ADJUST; \
	t.DrawingType = DRAWING_TEXT; \
	t.MultiLineLabel = true

#define UI_NewTextArray(t, size) \
	s_UseTool *t = new s_UseTool[size];  \
	for (int _t_i_ = 0; _t_i_ < size; _t_i_++) { t[_t_i_].Clear(); \
	t[_t_i_].LineNumber = ++LineNumber; t[_t_i_].UseRelativeVerticalValues = 0; t[_t_i_].AddMethod = UTAM_ADD_OR_ADJUST; \
	t[_t_i_].DrawingType = DRAWING_TEXT; \
	t[_t_i_].MultiLineLabel = true; } 

/* --- LINES ---
Line type:
DRAWING_LINE: Draws a Line on the chart.
DRAWING_RAY: Draws a Ray on the chart.
DRAWING_HORIZONTALLINE: This tool draws a Horizontal line drawing on the chart.
DRAWING_HORIZONTAL_RAY: Draws a Horizontal Ray on the chart.
DRAWING_VERTICALLINE: This tool draws a Vertical line drawing on the chart.

Line style:
LINESTYLE_SOLID, LINESTYLE_DASH, LINESTYLE_DOT, LINESTYLE_DASHDOT, and LINESTYLE_DASHDOTDOT.
*/
#define UI_NewLine(t, type, style, width, color, undergraph) \
	s_UseTool t; t.Clear(); \
	t.LineNumber = ++LineNumber; t.UseRelativeVerticalValues = 0; t.AddMethod = UTAM_ADD_OR_ADJUST; \
	t.DrawingType = (type); \
	t.LineStyle = (style); \
	t.LineWidth = (width); \
	t.DrawUnderneathMainGraph = (undergraph); \
	t.Color = (color) 

#define UI_NewLineArray(t, size, type, style, width, color, undergraph) \
	s_UseTool *t = new s_UseTool[size]; \
	for (int _t_i_ = 0; _t_i_ < size; _t_i_++) { t[_t_i_].Clear(); \
	t[_t_i_].LineNumber = ++LineNumber; t[_t_i_].UseRelativeVerticalValues = 0; t[_t_i_].AddMethod = UTAM_ADD_OR_ADJUST; \
	t[_t_i_].DrawingType = (type); \
	t[_t_i_].LineStyle = (style); \
	t[_t_i_].LineWidth = (width); \
	t[_t_i_].DrawUnderneathMainGraph = (undergraph); \
	t[_t_i_].Color = (color); }

/* --- MARKERS ---
Marker type:
MARKER_POINT: Draws a point.
MARKER_DASH: Draws a dash.
MARKER_SQUARE: Draws a square.
MARKER_STAR: Draws a star.
MARKER_PLUS: Draws a "+".
MARKER_X: Draws an "X".
MARKER_ARROWUP: Draws an up arrow.
MARKER_ARROWDOWN: Draws a down arrow.
MARKER_ARROWRIGHT: Draws a right arrow.
MARKER_ARROWLEFT: Draws a left arrow.
MARKER_TRIANGLEUP: Draws a up triangle.
MARKER_TRIANGLEDOWN: Draws a down triangle.
MARKER_TRIANGLERIGHT: Draws a right triangle.
MARKER_TRIANGLELEFT: Draws a left triangle.
MARKER_DIAMOND: Draws a diamond.
*/
#define UI_NewMarker(t, type, height, color) \
	s_UseTool t; t.Clear(); \
	t.LineNumber = ++LineNumber; t.UseRelativeVerticalValues = 0; t.AddMethod = UTAM_ADD_OR_ADJUST; \
	t.DrawingType = DRAWING_MARKER; \
	t.MarkerType = (type); \
	t.MarkerSize = (height); \
	t.Color = (color)

#define UI_NewMarkerArray(t, size, type, height, color) \
	s_UseTool *t = new s_UseTool[size]; \
for (int _t_i_ = 0; _t_i_ < size; _t_i_++) { t[_t_i_].Clear(); \
	t[_t_i_].LineNumber = ++LineNumber; t[_t_i_].UseRelativeVerticalValues = 0; t[_t_i_].AddMethod = UTAM_ADD_OR_ADJUST; \
	t[_t_i_].DrawingType = DRAWING_MARKER; \
	t[_t_i_].MarkerType = (type); \
	t[_t_i_].MarkerSize = (height); \
	t[_t_i_].Color = (color); }


/* --- Filled areas with borders: RECTANGLE BOXES, Triangles... ---- */
#define UI_SHAPE_BOX DRAWING_RECTANGLEHIGHLIGHT
#define UI_SHAPE_TRIANGLE DRAWING_TRIANGLE
#define UI_SHAPE_ELLIPS DRAWING_ELLIPSEHIGHLIGHT

#define UI_NewShape(t, type, borderColor, fillColor, transperency, undergraph ) \
	s_UseTool t; t.Clear(); \
	t.LineNumber = ++LineNumber; t.UseRelativeVerticalValues = 0; t.AddMethod = UTAM_ADD_OR_ADJUST; \
	t.DrawingType =  type; \
	t.Color  = (borderColor); \
	t.SecondaryColor = (fillColor); \
	t.TransparencyLevel = (transperency); \
	t.DrawUnderneathMainGraph = (undergraph)

#define UI_NewShapeArray(t, type, size, borderColor, fillColor, transperency, undergraph ) \
	s_UseTool *t = new s_UseTool[size]; \
for (int _t_i_ = 0; _t_i_ < size; _t_i_++) { t[_t_i_].Clear(); \
	t[_t_i_].LineNumber = ++LineNumber; t[_t_i_].UseRelativeVerticalValues = 0; t[_t_i_].AddMethod = UTAM_ADD_OR_ADJUST; \
	t[_t_i_].DrawingType = type; \
	t[_t_i_].Color  = (borderColor); \
	t[_t_i_].SecondaryColor = (fillColor); \
	t[_t_i_].TransparencyLevel = (transperency); \
	t[_t_i_].DrawUnderneathMainGraph = (undergraph); }


//———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
// MANIPULATING WITH OBJETS PROPERTIES
//———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
// x-scale in % in SC using [0...150] scale, but I prefere [0...100], so: t.BeginDateTime = (x)*1.5;

// VISIBILITY

#define UI_Use(t) { scptr->UseTool(t); }

#define UI_Show(t) { if ( t.BeginValue < 0 ) { t.BeginValue = -t.BeginValue; t.EndValue = -t.EndValue; scptr->UseTool(t); } }

#define UI_Hide(t) { if ( t.BeginValue >= 0 ) { t.BeginValue = -t.BeginValue; t.EndValue = -t.EndValue; scptr->UseTool(t); } }

#define UI_Delete(t) scptr->DeleteACSChartDrawing(scptr->ChartNumber, TOOL_DELETE_CHARTDRAWING, t.LineNumber)

#define UI_DeleteArray(t, size) { \
	for (int _t_i_ = 0; _t_i_ < size; _t_i_++) \
	{ scptr->DeleteACSChartDrawing(scptr->ChartNumber, TOOL_DELETE_CHARTDRAWING, t[_t_i_].LineNumber); } \
	delete [] t; } 



// PLACEMENT

#define UI_XY(t, x, y) { t.UseRelativeVerticalValues = 1; t.BeginDateTime = (x)*1.5; t.BeginValue = (float)(y); } 

#define UI_Price(t, p) t.BeginValue = (p)

#define UI_Bar(t, b) t.BeginIndex = (b)

#define UI_Time(t, tm) t.BeginDateTime = (tm)

#define UI_BarPrice(t, b, p) t.BeginIndex = (b), t.BeginValue = (p)

#define UI_TimePrice(t, tm, p) t.BeginDateTime = (tm), t.BeginValue = (p)

#define UI_BarPrice2(t, bs, ps, be, pe) { t.BeginIndex = (bs); t.BeginValue = (float)(ps); t.EndIndex = (be); t.EndValue = (float)(pe); }

#define UI_TimePrice2(t, tms, ps, tme, pe) { t.BeginDateTime = (tms); t.BeginValue = (float)(ps); t.BeginDateTime = (tme); t.EndValue = (float)(pe); }

#define UI_BarPrice3(t, bs, ps, be, pe, b3, p3) { t.BeginIndex = (bs); t.BeginValue = (float)(ps); t.EndIndex = (be); t.EndValue = (float)(pe); t.ThirdIndex = (b3); t.ThirdValue = (float)(p3); }

#define UI_TimePrice3(t, tms, ps, tme, pe, tm3, p3) { t.BeginDateTime = (tms); t.BeginValue = (float)(ps); t.BeginDateTime = (tme); t.EndValue = (float)(pe); t.ThirdDateTime = (tm3); t.ThirdValue = (float)(p3); }

// CONTENT

#define UI_Text(t, fmtstr, ...) t.Text.Format(fmtstr, ##__VA_ARGS__);

#define UI_Font(t, fontName, fontSize) { t.FontFace = (fontName); t.FontSize = (fontSize); }	

#define UI_Color(t, foreColor) t.Color = (foreColor)

#define UI_Back(t, backColor) t.TransparentLabelBackground = ( (backColor) < 0) ? 1 : 0, t.FontBackColor = (backColor) 

#define UI_Fill(t, fillColor) t.SecondaryColor = (fillColor) 

#define UI_Transperency(t, transperency) t.TransparencyLevel = (transperency)

#define UI_Width(t, width) t.LineWidth = (width)

Testing demo code

This code is an example to test main functions of ats-GUI.h. Every chart study recalculate generate pseudorandom (based on current seconds of time) modifications to texts, colors, positions and tools types. So you can see that codes is working

#include "sierrachart.h"
#include "SCString.h"

SCDLLName("GroupName")

SCSFExport scsf_StudyName(SCStudyGraphRef sc)
{
	UI_INIT(100000, sc);

	if (sc.SetDefaults) // Set the configuration variables and defaults
	{
		sc.GraphName = "ZZStat";
		sc.FreeDLL = 1;  // 1-when develop, 0-for (release to improve performance).
		sc.AutoLoop = 1;  // Auto looping is enabled.
		
		sc.GraphRegion = 0; // Use the main price graph region
		return;
	}

	if (sc.Index != sc.ArraySize - 1) return; // This is not last bar

	// Main algorithm body starting from here
	// get seconds for moving
	time_t t = time(0); struct tm * now = localtime(&t); int sec = now->tm_sec;

	int x, y, b; 
	float p;
	COLORREF fclr, bclr;

	// Absolute positioning text with color change
	UI_NewText(txy); 
	x = sec * 100 / 60; y = sec;
	fclr = RGB(sec * 255 / 60, 255 - sec * 255 / 60, sec);
	bclr = RGB(255 - sec * 255 / 60, sec * 255 / 60, 255 - sec);
	UI_Color(txy, fclr);
	UI_Back(txy, bclr);
	UI_XY(txy, x, y);
	UI_Text(txy, "Moved to X=%d Y=%d\nfclr=%d bclr=%d", x, y, fclr, bclr);
	UI_Use(txy);

	// Price positioning text with font change
	UI_NewText(tp);
	x = 90; y = sec;
	fclr = RGB(190, 190, 190);
	UI_Color(tp, fclr);
	b = sc.ArraySize - sec;
	p = sc.Low[b];
	UI_Price(tp, p);
	UI_Bar(tp, b);
	UI_Font(tp, "Courier New", sec/10+6);
	UI_Text(tp, "Moved to low on:\nbar=%d\nprice=%4.2f\nsize=%d", -sec, p, sec / 10 + 6);
	UI_Use(tp);

	// Hline
	fclr = RGB(255 - sec * 255 / 60, sec * 255 / 60, 255 - sec);
	UI_NewLine(hl, DRAWING_HORIZONTALLINE, sec % 10, sec / 10 + 1, fclr, 0);
	UI_Color(hl, fclr);
	UI_Price(hl, p);
	UI_Use(hl);

	// Vline
	fclr = RGB(255 - sec * 255 / 60, sec * 255 / 60, 255 - sec);
	UI_NewLine(vl, DRAWING_VERTICALLINE, sec % 10, sec / 10 + 1, fclr, 0);
	UI_Color(vl, fclr);
	UI_Bar(vl, b);
	UI_Use(vl);

	// Trend line
	b = sc.ArraySize - sec - 3;
	fclr = RGB(255 - sec * 255 / 60, sec * 255 / 60, 255 - sec);
	UI_NewLine(tl, DRAWING_RAY, LINESTYLE_DOT, 1, RGB(190, 90, 90), 0);
	UI_Color(tl, fclr);
	UI_BarPrice2(tl, b, sc.Low[b], sc.ArraySize - 1, sc.Close[sc.ArraySize - 1]);
	UI_Use(tl);

	// Marker
	fclr = RGB(255 - sec * 255 / 60, sec * 255 / 60, 255 - sec);
	UI_NewMarker(m, MARKER_TRIANGLEDOWN, sec % 10 + 1, RGB(190, sec, sec));
	UI_BarPrice(m, b, sc.High[b]);
	UI_Use(m);


	// Box
	b = sc.ArraySize - sec - 3;
	fclr = RGB(255 - sec * 255 / 60, sec * 255 / 60, 255 - sec);
	UI_NewShape(bx, UI_SHAPE_BOX, RGB(190, 90, 90), RGB(90, 40, 40), 50, 0);
	UI_Fill(bx, fclr);
	UI_BarPrice2(bx, b, sc.Low[b], sc.ArraySize - 1, sc.Close[sc.ArraySize - 1]);
	UI_Transperency(bx, sec);
	UI_Use(bx);


	int size = 10;
	UI_NewTextArray(ta, size);

	// Text array
	for (int i = 0; i < size; i++) {
		fclr = RGB(i * 255 / 60, 255 - i * 255 / 60, i);
		bclr = RGB(255 - i * 255 / 60, i * 255 / 60, 255 - i);
		UI_Color(ta[i], fclr);
		UI_Back(ta[i], bclr);
		UI_XY(ta[i], i, i*4);
		UI_Text(ta[i], "%d) item (%d-#%d)", i, sc.ChartNumber, ta[i].LineNumber);
		ta[i].AddAsUserDrawnDrawing = 0;
		UI_Use(ta[i]);
	}
	
	// misk arrays
	b = sc.ArraySize - 60;
	UI_NewLineArray(vla, size, DRAWING_RAY, LINESTYLE_DOT, 2, fclr, 0);
	UI_NewMarkerArray(ma, size, MARKER_TRIANGLEUP, 4, RGB(190, 0, 100));
	UI_NewShapeArray(bxa, UI_SHAPE_TRIANGLE, size, RGB(190, 90, 90), RGB(90, 40, 40), 50, 0);
	for (int i = 0; i < size; i++) {
		fclr = RGB(255 - i * 10, i*10, i*10);
		UI_Color(vla[i], fclr);
		UI_Color(ma[i], fclr);
		ma[i].MarkerSize = i/2+2;
		UI_BarPrice2(vla[i], b - i, sc.High[b - i] + 0.1, b - i, sc.High[b - i] + 100000);
		UI_BarPrice2(ma[i], b - i, sc.High[b - i] + 0.01, b - i, sc.High[b - i] + 100000);
		UI_BarPrice3(bxa[i], b - i, 27.7, b - i+4, 27.4, b - i+6, 27.1);
		UI_Use(vla[i]);
		UI_Use(ma[i]); 
		UI_Use(bxa[i]);
	}

	
	UI_Delete(ta[3]);
	UI_Delete(ta[5]);
	
	// on deattach study - clean up arrays
	if (sc.LastCallToFunction) 
	{ 
		UI_DeleteArray(ta, size);
		UI_DeleteArray(vla, size);
		UI_DeleteArray(ma, size);
		UI_DeleteArray(bxa, size);
		return;
	}
	
}

Difference example

Take a look on this two samples. Upper variant practically don't need any comments - everything that it done is clear directly from the source code:

UI_NewText(Panel1, 1254);	
UI_Text(Panel1, "Demo text #%d", 1);
UI_XY(Panel1, 100, 100);
UI_Color(Panel1, RGB(r,g,b));
UI_Back(Panel1, RGB(g/2,r/3,b*2)); 

This common look of multiline. Certainly you need or good memory or help file to understand what this code done.

s_UseTool t; 
t.LineNumber = (ln); 
t.AddMethod = UTAM_ADD_OR_ADJUST; 
t.DrawingType = DRAWING_TEXT; 
t.MultiLineLabel = true;
t.UseRelativeVerticalValues = 1; 
t.BeginDateTime  = (x)*1.50; 
t.BeginValue = (y); 
............... more then 10 lines more
sc.UseTool(t);

But it done the same thing as upper example. So - why do not write shorter and clearer codes? ;)

 
Copyright © 2014 AlgoTrading.Solutions