EasyAndFastMod/Controls/Graph.mqh

380 lines
29 KiB
MQL5
Raw Permalink Normal View History

2026-01-15 07:23:17 -05:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| Graph.mqh |
//| Copyright 2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "..\Element.mqh"
//+------------------------------------------------------------------+
//| ;0AA 4;O A>740=8O 3@0D8:0 |
//+------------------------------------------------------------------+
class CGraph : public CElement
{
private:
//--- 1J5:BK 4;O A>740=8O M;5<5=B0
CGraphic m_graph;
//--- >;=>M:@0==K9 @568<
bool m_is_fullscreen_mode;
//--- @5404CI85 @07<5@K 8 ?>;>65=85 4;O @568<0 ">;=>M:@0==K9 @568<"
int m_prev_x;
int m_prev_y;
int m_prev_width;
int m_prev_height;
//---
public:
CGraph(void);
~CGraph(void);
//--- 5B>4K 4;O A>740=8O M;5<5=B0
bool CreateGraph(const int x_gap,const int y_gap);
//---
private:
void InitializeProperties(const int x_gap,const int y_gap);
bool CreateGraphic(void);
//---
public:
//--- >72@0I05B C:070B5;L =0 3@0D8:
CGraphic *GetGraphicPointer(void) { return(::GetPointer(m_graph)); }
//--- 7<5=5=85 @07<5@>2
void Resize(const int width,const int height);
//--- >;=>M:@0==K9 @568<
void IsFullScreenMode(const bool mode) { m_is_fullscreen_mode=mode; };
void FullScreenMode(const bool mode=true);
//---
public:
//--- 1@01>BG8: A>1KB89 3@0D8:0
virtual void OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- 5@5<5I5=85 M;5<5=B0
virtual void Moving(const bool only_visible=true);
//--- #?@02;5=85
virtual void Show(void);
virtual void Hide(void);
virtual void Reset(void);
virtual void Delete(void);
//--- @8<5=5=85 ?>A;54=8E 87<5=5=89
virtual void Update(const bool redraw=false);
//--- (1) #AB0=>2:0, (2) A1@>A ?@8>@8B5B>2 =0 =068B85 ;52>9 :=>?:8 <KH8
virtual void SetZorders(void);
virtual void ResetZorders(void);
//---
private:
//--- 1@01>B:0 =060B8O =0 3@0D8:5
bool OnClickGraph(const string pressed_object);
//--- 7<5=8BL H8@8=C ?> ?@02><C :@0N >:=0
virtual void ChangeWidthByRightWindowSide(void);
//--- 7<5=8BL 2KA>BC ?> =86=5<C :@0N >:=0
virtual void ChangeHeightByBottomWindowSide(void);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CGraph::CGraph(void) : m_prev_x(0),
m_prev_y(0),
m_prev_width(0),
m_prev_height(0),
m_is_fullscreen_mode(true)
{
//--- !>E@0=8< 8<O :;0AA0 M;5<5=B0 2 107>2>< :;0AA5
CElementBase::ClassName(CLASS_NAME);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CGraph::~CGraph(void)
{
}
//+------------------------------------------------------------------+
//| 1@01>BG8: A>1KB89 |
//+------------------------------------------------------------------+
void CGraph::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
//--- 1@01>B:0 A>1KB8O ?5@5<5I5=8O :C@A>@0
if(id==CHARTEVENT_MOUSE_MOVE)
{
return;
}
//--- 1@01>B:0 A>1KB8O =060B8O ;52>9 :=>?:8 <KH8 =0 >1J5:B5
if(id==CHARTEVENT_OBJECT_CLICK)
{
if(OnClickGraph(sparam))
return;
//---
return;
}
}
//+------------------------------------------------------------------+
//| !>740QB 3@0D8: |
//+------------------------------------------------------------------+
bool CGraph::CreateGraph(const int x_gap,const int y_gap)
{
//--- K9B8, 5A;8 =5B C:070B5;O =0 3;02=K9 M;5<5=B
if(!CElement::CheckMainPointer())
return(false);
//--- =8F80;870F8O A2>9AB2
InitializeProperties(x_gap,y_gap);
//--- !>740=85 M;5<5=B0
if(!CreateGraphic())
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+
//| =8F80;870F8O A2>9AB2 |
//+------------------------------------------------------------------+
void CGraph::InitializeProperties(const int x_gap,const int y_gap)
{
m_x =CElement::CalculateX(x_gap);
m_y =CElement::CalculateY(y_gap);
//--- 0AAG8B05< @07<5@K
m_x_size =(m_x_size<1 || m_auto_xresize_mode)? m_main.X2()-m_x-m_auto_xresize_right_offset : m_x_size;
m_y_size =(m_y_size<1 || m_auto_yresize_mode)? m_main.Y2()-m_y-m_auto_yresize_bottom_offset : m_y_size;
m_prev_width =m_x_size;
m_prev_height =m_y_size;
//--- !>E@0=8< @07<5@K
CElementBase::XSize(m_x_size);
CElementBase::YSize(m_y_size);
//--- BABC?K >B :@09=59 B>G:8
CElementBase::XGap(x_gap);
CElementBase::YGap(y_gap);
}
//+------------------------------------------------------------------+
//| !>740QB >1J5:B |
//+------------------------------------------------------------------+
bool CGraph::CreateGraphic(void)
{
//--- >@@5:B8@>2:0 @07<5@>2
m_x_size =(m_x_size<1)? 50 : m_x_size;
m_y_size =(m_y_size<1)? 20 : m_y_size;
//--- $>@<8@>20=85 8<5=8 >1J5:B0
string name=CElementBase::ElementName("graph");
//--- >>@48=0BK
int x2=m_x+m_x_size;
int y2=m_y+m_y_size;
//--- #40;8< >1J5:B, 5A;8 >= 5ABL
if(::ObjectFind(m_chart_id,name)>=0)
{
::ObjectDelete(m_chart_id,name);
}
//--- !>740=85 >1J5:B0
if(!m_graph.Create(m_chart_id,name,m_subwin,m_x,m_y,x2,y2))
return(false);
//--- !2>9AB20
::ObjectSetString(m_chart_id,m_graph.ChartObjectName(),OBJPROP_TOOLTIP,"\n");
//--- # 2A5E M;5<5=B>2, :@><5 D>@<K, ?@8>@8B5B 1>;LH5, G5< C 3;02=>3> M;5<5=B0
Z_Order(m_main.Z_Order()+1);
::ObjectSetInteger(m_chart_id,m_graph.ChartObjectName(),OBJPROP_ZORDER,m_zorder);
return(true);
}
//+------------------------------------------------------------------+
//| 5@5<5I5=85 |
//+------------------------------------------------------------------+
void CGraph::Moving(const bool only_visible=true)
{
//--- K9B8, 5A;8 M;5<5=B A:@KB
if(only_visible)
if(!CElementBase::IsVisible())
return;
//--- A;8 ?@82O7:0 A?@020
if(m_anchor_right_window_side)
{
//--- !>E@0=5=85 :>>@48=0B 2 ?>;OE M;5<5=B0
CElementBase::X(m_main.X2()-XGap());
}
else
{
CElementBase::X(m_main.X()+XGap());
}
//--- A;8 ?@82O7:0 A=87C
if(m_anchor_bottom_window_side)
{
CElementBase::Y(m_main.Y2()-YGap());
}
else
{
CElementBase::Y(m_main.Y()+YGap());
}
//--- 1=>2;5=85 :>>@48=0B 3@0D8G5A:8E >1J5:B>2
::ObjectSetInteger(m_chart_id,m_graph.ChartObjectName(),OBJPROP_XDISTANCE,X());
::ObjectSetInteger(m_chart_id,m_graph.ChartObjectName(),OBJPROP_YDISTANCE,Y());
}
//+------------------------------------------------------------------+
//| >:07K205B ?C=:B <5=N |
//+------------------------------------------------------------------+
void CGraph::Show(void)
{
//--- K9B8, 5A;8 M;5<5=B C65 2848<
if(CElementBase::IsVisible())
return;
//--- !45;0BL 2848<K<8 2A5 >1J5:BK
::ObjectSetInteger(m_chart_id,m_graph.ChartObjectName(),OBJPROP_TIMEFRAMES,OBJ_ALL_PERIODS);
//--- !>AB>O=85 2848<>AB8
CElementBase::IsVisible(true);
//--- 1=>28BL ?>;>65=85 >1J5:B>2
Moving();
}
//+------------------------------------------------------------------+
//| !:@K205B ?C=:B <5=N |
//+------------------------------------------------------------------+
void CGraph::Hide(void)
{
//--- K9B8, 5A;8 M;5<5=B A:@KB
if(!CElementBase::IsVisible())
return;
//--- !:@KBL 2A5 >1J5:BK
::ObjectSetInteger(m_chart_id,m_graph.ChartObjectName(),OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
//--- !>AB>O=85 2848<>AB8
CElementBase::IsVisible(false);
}
//+------------------------------------------------------------------+
//| 5@5@8A>2:0 |
//+------------------------------------------------------------------+
void CGraph::Reset(void)
{
//--- K945<, 5A;8 M;5<5=B 2K?040NI89
if(CElementBase::IsDropdown())
return;
//--- !:@KBL 8 ?>:070BL
Hide();
Show();
}
//+------------------------------------------------------------------+
//| #40;5=85 |
//+------------------------------------------------------------------+
void CGraph::Delete(void)
{
//--- #40;8BL >1J5:BK A5@89
int total=m_graph.CurvesTotal();
for(int i=total-1; i>=0; i--)
m_graph.CurveRemoveByIndex(i);
//--- #40;8BL >1J5:B 3@0D8:0
m_graph.Destroy();
//--- =8F80;870F8O ?5@5<5==KE 7=0G5=8O<8 ?> C<>;G0=8N
CElementBase::IsVisible(true);
}
//+------------------------------------------------------------------+
//| 1=>2;5=85 M;5<5=B0 |
//+------------------------------------------------------------------+
void CGraph::Update(const bool redraw=false)
{
//--- @8<5=8BL
m_graph.Update();
}
//+------------------------------------------------------------------+
//| #AB0=>2:0 ?@8>@8B5B>2 |
//+------------------------------------------------------------------+
void CGraph::SetZorders(void)
{
::ObjectSetInteger(m_chart_id,m_graph.ChartObjectName(),OBJPROP_ZORDER,m_zorder);
}
//+------------------------------------------------------------------+
//| !1@>A ?@8>@8B5B>2 |
//+------------------------------------------------------------------+
void CGraph::ResetZorders(void)
{
::ObjectSetInteger(m_chart_id,m_graph.ChartObjectName(),OBJPROP_ZORDER,WRONG_VALUE);
}
//+------------------------------------------------------------------+
//| 7<5=5=85 @07<5@>2 |
//+------------------------------------------------------------------+
void CGraph::Resize(const int width,const int height)
{
m_x_size=width;
m_y_size=height;
//--- #40;8BL >1J5:B
::ObjectDelete(m_chart_id,m_graph.ChartObjectName());
//--- !>740BL 3@0D8:
CreateGraphic();
//--- !:@KBL 2A5 >1J5:BK
if(!CElementBase::IsVisible())
::ObjectSetInteger(m_chart_id,m_graph.ChartObjectName(),OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
}
//+------------------------------------------------------------------+
//| #?@02;5=85 ?>;=>M:@0==K< @568<>< 3@0D8:0 |
//+------------------------------------------------------------------+
void CGraph::FullScreenMode(const bool mode)
{
//--- 7<5=8BL @07<5@K
int chart_width =m_chart.WidthInPixels();
int chart_height =m_chart.HeightInPixels(0);
//---
if(chart_width-1==m_x_size && chart_height-1==m_y_size)
{
Resize(m_prev_width,m_prev_height);
::ObjectSetInteger(m_chart_id,m_graph.ChartObjectName(),OBJPROP_XDISTANCE,m_prev_x);
::ObjectSetInteger(m_chart_id,m_graph.ChartObjectName(),OBJPROP_YDISTANCE,m_prev_y);
}
else
{
m_prev_x =m_x;
m_prev_y =m_y;
m_prev_width =m_x_size;
m_prev_height =m_y_size;
Resize(chart_width-1,chart_height-1);
::ObjectSetInteger(m_chart_id,m_graph.ChartObjectName(),OBJPROP_XDISTANCE,1);
::ObjectSetInteger(m_chart_id,m_graph.ChartObjectName(),OBJPROP_YDISTANCE,1);
}
//---
m_graph.Redraw(true);
m_graph.Update();
m_chart.Redraw();
}
//+------------------------------------------------------------------+
//| 060B85 =0 3@0D8: |
//+------------------------------------------------------------------+
bool CGraph::OnClickGraph(const string pressed_object)
{
//--- K945<, 5A;8 (1) GC6>5 8<O >1J5:B0 8;8 (2) 2K:;NG5= ?>;=>M:@0==K9 @568<
if(m_graph.ChartObjectName()!=pressed_object || !m_is_fullscreen_mode)
return(false);
//--- 7<5=8BL @07<5@K
FullScreenMode();
return(true);
}
//+------------------------------------------------------------------+
//| 7<5=8BL H8@8=C ?> ?@02><C :@0N D>@<K |
//+------------------------------------------------------------------+
void CGraph::ChangeWidthByRightWindowSide(void)
{
//--- K9B8, 5A;8 2:;NG5= @568< D8:A0F88 : ?@02><C :@0N D>@<K
if(m_anchor_right_window_side)
return;
//--- 07<5@K
int x_size=0;
//--- 0AAG8B0BL @07<5@
x_size=m_main.X2()-X()-m_auto_xresize_right_offset;
//--- 5 87<5=OBL @07<5@, 5A;8 <5=LH5 CAB0=>2;5==>3> >3@0=8G5=8O
if(x_size<200 || x_size==m_x_size)
return;
//---
m_prev_width=x_size;
//--- #AB0=>28BL =>2K9 @07<5@
CElementBase::XSize(x_size);
Resize(x_size,m_graph.Height());
//--- 1=>28BL 40==K5 =0 3@0D8:5
m_graph.Redraw(true);
}
//+------------------------------------------------------------------+
//| 7<5=8BL 2KA>BC ?> =86=5<C :@0N >:=0 |
//+------------------------------------------------------------------+
void CGraph::ChangeHeightByBottomWindowSide(void)
{
//--- K9B8, 5A;8 2:;NG5= @568< D8:A0F88 : =86=5<C :@0N D>@<K
if(m_anchor_bottom_window_side)
return;
//--- 07<5@K
int y_size=0;
//--- 0AAG8B0BL @07<5@
y_size=m_main.Y2()-Y()-m_auto_yresize_bottom_offset;
//--- 5 87<5=OBL @07<5@, 5A;8 <5=LH5 CAB0=>2;5==>3> >3@0=8G5=8O
if(y_size<200 || y_size==m_y_size)
return;
//---
m_prev_height=y_size;
//--- #AB0=>28BL =>2K9 @07<5@
CElementBase::YSize(y_size);
Resize(m_graph.Width(),y_size);
//--- 1=>28BL 40==K5 =0 3@0D8:5
m_graph.Redraw(true);
}
//+------------------------------------------------------------------+