Biblioteca2/Include/Telegram/Comment.mqh

411 lines
13 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 14:43:36 +02:00
//+------------------------------------------------------------------+
//| Comment.mqh |
//| avoitenko |
//| https://login.mql5.com/en/users/avoitenko |
//+------------------------------------------------------------------+
#property copyright "avoitenko"
#property link "https://login.mql5.com/en/users/avoitenko"
#property version "1.00"
#property strict
#include <Canvas/Canvas.mqh>
#include <Arrays/List.mqh>
//---
#define EVENT_NO_EVENTS 0
#define EVENT_MOVE 1
#define EVENT_CHANGE 2
//+------------------------------------------------------------------+
//| TComment |
//+------------------------------------------------------------------+
class TComment : public CObject
{
public:
string text;
color colour;
};
//+------------------------------------------------------------------+
//| CComment |
//+------------------------------------------------------------------+
class CComment
{
private:
CPoint m_temp;
CCanvas m_comment;
CPoint m_pos;
CList m_list;
CSize m_size;
//---
string m_name;
string m_font_name;
int m_font_size;
bool m_font_bold;
double m_font_interval;
color m_border_color;
color m_back_color;
uchar m_back_alpha;
bool m_graph_mode;
bool m_auto_colors;
color m_auto_back_color;
color m_auto_text_color;
color m_auto_border_color;
color m_chart_back_color;
//+------------------------------------------------------------------+
color Color2Gray(const color value)
{
int gray=(int)round(0.3*GETRGBR(value)+0.59*GETRGBG(value)+0.11*GETRGBB(value));
if(gray>255) gray=255;
return((color)ARGB(0,gray,gray,gray));
}
//+------------------------------------------------------------------+
uchar GrayChannel(const color value)
{
int gray=(int)round(0.3*GETRGBR(value)+0.59*GETRGBG(value)+0.11*GETRGBB(value));
if(gray>255) gray=255;
return((uchar)gray);
}
//+------------------------------------------------------------------+
color Bright(const color value,const int percent)
{
int r,g,b;
//---
r=GETRGBR(value);
g=GETRGBG(value);
b=GETRGBB(value);
//---
if(percent>=0)
{
r+=(255-r)*percent/100;
if(r>255)r=255;
g+=(255-g)*percent/100;
if(g>255)g=255;
b+=(255-b)*percent/100;
if(b>255)b=255;
}
else
{
r+=r*percent/100;
if(r<0)r=0;
g+=g*percent/100;
if(g<0)g=0;
b+=b*percent/100;
if(b<0)b=0;
}
//---
return(ARGB(0,r,g,b));
}
//+------------------------------------------------------------------+
void CalcColors()
{
m_auto_back_color=(color)ChartGetInteger(0,CHART_COLOR_BACKGROUND);
color m_back_gray=Color2Gray(m_auto_back_color);
uchar channel=GrayChannel(m_back_gray);
//---
if(channel>120)
{
if(m_back_color==clrNONE)
m_auto_border_color=clrNONE;
else
m_auto_border_color=Bright(m_back_gray,-30);
m_auto_text_color=Bright(m_back_gray,-80);
}
else
{
if(m_back_color==clrNONE)
m_auto_border_color=clrNONE;
else
m_auto_border_color=Bright(m_back_gray,30);
m_auto_text_color=Bright(m_back_gray,80);
}
}
public:
//+------------------------------------------------------------------+
void CComment(void)
{
m_name=NULL;
m_font_name="Lucida Console";
m_font_size=14;
m_font_bold=false;
m_font_interval=1.7;
m_border_color=clrNONE;
m_back_color=clrBlack;
m_back_alpha=255;
m_graph_mode=true;
m_auto_colors=false;
m_chart_back_color=(color)ChartGetInteger(0,CHART_COLOR_BACKGROUND);
m_auto_back_color=clrBlack;
m_auto_border_color=clrNONE;
//---
ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
};
//+------------------------------------------------------------------+
void Create(const string name,const uint x,const uint y)
{
m_name=name;
m_pos.x=(int)x;
m_pos.y=(int)y;
};
//+------------------------------------------------------------------+
int CoordY()
{
return(m_pos.y);
}
//+------------------------------------------------------------------+
int CoordX()
{
return(m_pos.x);
}
//+------------------------------------------------------------------+
void Move(const uint x,const uint y)
{
m_pos.x=(int)x;
m_pos.y=(int)y;
if(ObjectGetInteger(0,m_name,OBJPROP_XDISTANCE)!=m_pos.x)
ObjectSetInteger(0,m_name,OBJPROP_XDISTANCE,m_pos.x);
if(ObjectGetInteger(0,m_name,OBJPROP_YDISTANCE)!=m_pos.y)
ObjectSetInteger(0,m_name,OBJPROP_YDISTANCE,m_pos.y);
};
//+------------------------------------------------------------------+
void SetAutoColors(const bool value)
{
m_auto_colors=value;
if(value)
CalcColors();
}
//+------------------------------------------------------------------+
void SetGraphMode(const bool value)
{
m_graph_mode=value;
};
//+------------------------------------------------------------------+
void SetText(const int row,const string text,const color colour)
{
if(row<0)
return;
//---
int total=m_list.Total();
if(row<total)
{
TComment *item=m_list.GetNodeAtIndex(row);
item.text=text;
item.colour=colour;
}
else
{
//--- create new one string
for(int i=total; i<=row; i++)
{
m_list.Add(new TComment);
TComment *item=m_list.GetLastNode();
if(row==i)
{
item.text=text;
item.colour=colour;
}
else
{
item.text="";
item.colour=clrNONE;
}
}
}
}
//+------------------------------------------------------------------+
void SetFont(const string font_name,const int font_size,const bool bold,const double font_interval)
{
m_font_name=font_name;
m_font_size=font_size;
m_font_bold=bold;
m_font_interval=font_interval;
}
//+------------------------------------------------------------------+
void SetTransparency(const uchar alpha)
{
m_back_alpha=alpha;
}
//+------------------------------------------------------------------+
void SetColor(const color border,const color back,const uchar alpha)
{
m_border_color=border;
m_back_color=back;
m_back_alpha=alpha;
}
//+------------------------------------------------------------------+
void Destroy()
{
if(!m_graph_mode)
Comment("");
m_comment.Destroy();
m_name=NULL;
};
//+------------------------------------------------------------------+
void Clear()
{
m_list.Clear();
};
//+------------------------------------------------------------------+
int OnChartEvent(const int id,const long lparam,const double dparam,const string sparam)
{
//--- mouse position
CPoint p;
p.x = (int)lparam;
p.y = (int)dparam;
//---
if(id==CHARTEVENT_MOUSE_MOVE)
{
//--- panel size
CSize psize;
psize.cx=(int)ObjectGetInteger(0,m_name,OBJPROP_XSIZE);
psize.cy=(int)ObjectGetInteger(0,m_name,OBJPROP_YSIZE);
//--- panel position
CPoint pan;
pan.x=(int)ObjectGetInteger(0,m_name,OBJPROP_XDISTANCE);
pan.y=(int)ObjectGetInteger(0,m_name,OBJPROP_YDISTANCE);
//--- chart size
CSize screen;
screen.cx=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
screen.cy=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
if(sparam=="1")
{
//---
if(m_temp.x==-1 &&
p.x>=pan.x && p.x<pan.x+psize.cx &&
p.y>=pan.y && p.y<pan.y+psize.cy)
{
m_temp.x=p.x-pan.x;
}
//---
if(m_temp.y==-1 &&
p.x>=pan.x && p.x<pan.x+psize.cx &&
p.y>=pan.y && p.y<pan.y+psize.cy)
{
m_temp.y=p.y-pan.y;
}
//---
if(m_temp.x>=0 && m_temp.y>=0)
{
int new_x=p.x-m_temp.x;
if(new_x>screen.cx-psize.cx)new_x=screen.cx-psize.cx;
if(new_x<0)new_x=0;
int new_y=p.y-m_temp.y;
if(new_y>screen.cy-psize.cy)new_y=screen.cy-psize.cy;
if(new_y<0)new_y=0;
//---
ObjectSetInteger(0,m_name,OBJPROP_XDISTANCE,new_x);
m_pos.x=new_x;
ObjectSetInteger(0,m_name,OBJPROP_YDISTANCE,new_y);
m_pos.y=new_y;
ChartSetInteger(0,CHART_MOUSE_SCROLL,false);
#ifdef __MQL5__
ChartRedraw();
#endif
return(EVENT_MOVE);
}
}
else
{
m_temp.x=-1;
m_temp.y=-1;
ChartSetInteger(0,CHART_MOUSE_SCROLL,true);
}
}
//---
if(m_auto_colors && id==CHARTEVENT_CHART_CHANGE)
{
//--- changing background color event
if(m_chart_back_color!=(color)ChartGetInteger(0,CHART_COLOR_BACKGROUND))
{
CalcColors();
m_chart_back_color=(color)ChartGetInteger(0,CHART_COLOR_BACKGROUND);
Show();
return(EVENT_CHANGE);
}
}
//---
return(EVENT_NO_EVENTS);
}
//+------------------------------------------------------------------+
void Show()
{
int rows=m_list.Total();
//--- text mode
if(!m_graph_mode)
{
string text;
for(int i=0; i<rows; i++)
{
TComment *item=m_list.GetNodeAtIndex(i);
text+="\n"+item.text;
}
Comment(text);
return;
}
m_comment.FontSet(m_font_name,m_font_size,m_font_bold?FW_BOLD:0);
int text_height=m_comment.TextHeight(" ");
int max_height=(rows)*(int)round(text_height*m_font_interval)+text_height;
//--- calc max width
int max_width=0;
for(int i=0; i<rows; i++)
{
TComment *item=m_list.GetNodeAtIndex(i);
int width=m_comment.TextWidth(item.text);
if(width>max_width) max_width=width;
}
max_width+=text_height*2;
//--- create panel
if(ObjectFind(0,m_name)==-1)
{
m_comment.CreateBitmapLabel(0,0,m_name,m_pos.x,m_pos.y,max_width,max_height,COLOR_FORMAT_ARGB_NORMALIZE);
ObjectSetString(0,m_name,OBJPROP_TOOLTIP,"\n");
}
else
{
//--- resize panel
if(m_comment.Height()!=max_height ||
m_comment.Width()!=max_width)
{
if(!m_comment.Resize(max_width,max_height))
{
ObjectDelete(0,m_name);
ChartRedraw();
}
}
}
//---
m_comment.Erase(ColorToARGB(m_auto_colors?m_auto_back_color:m_back_color,m_back_alpha));
m_comment.Rectangle(0,0,max_width-1,max_height-1,ColorToARGB(m_auto_colors?m_auto_border_color:m_border_color));
//---
int h=text_height;
for(int i=0; i<rows; i++)
{
TComment *item=m_list.GetNodeAtIndex(i);
m_comment.TextOut(text_height,h,item.text,ColorToARGB(m_auto_colors?m_auto_text_color:item.colour));
h+=(int)round(text_height*m_font_interval);
}
//---
m_comment.Update();
}
};
//+------------------------------------------------------------------+