EasyAndFastMod/Controls/PicturesSlider.mqh

449 lines
38 KiB
MQL5
Raw Permalink Normal View History

2026-01-15 07:23:17 -05:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| PicturesSlider.mqh |
//| Copyright 2016, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "..\Element.mqh"
#include "Picture.mqh"
#include "Button.mqh"
#include "ButtonsGroup.mqh"
//--- 0@B8=:0 ?> C<>;G0=8N
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp64\\no_image.bmp"
//+------------------------------------------------------------------+
//| ;0AA 4;O A>740=8O A;0945@0 :0@B8=>: |
//+------------------------------------------------------------------+
class CPicturesSlider : public CElement
{
private:
//--- 1J5:BK 4;O A>740=8O M;5<5=B0
CPicture m_pictures[];
CButtonsGroup m_radio_buttons;
CButton m_left_arrow;
CButton m_right_arrow;
//--- 0AA82 :0@B8=>: (?CBL : :0@B8=:0<)
string m_file_path[];
//--- CBL : :0@B8=:5 ?> C<>;G0=8N
string m_default_path;
//--- BABC? 4;O :0@B8=>: ?> >A8 Y
int m_pictures_y_gap;
//--- BABC?K 4;O :=>?>:
int m_arrows_x_gap;
int m_arrows_y_gap;
//--- (8@8=0 @048>-:=>?:8
int m_radio_button_width;
//--- BABC?K 4;O @048>-:=>?>:
int m_radio_buttons_x_gap;
int m_radio_buttons_y_gap;
int m_radio_buttons_x_offset;
//---
public:
CPicturesSlider(void);
~CPicturesSlider(void);
//--- 5B>4K 4;O A>740=8O A;0945@0 :0@B8=>:
bool CreatePicturesSlider(const int x_gap,const int y_gap);
//---
private:
void InitializeProperties(const int x_gap,const int y_gap);
bool CreateCanvas(void);
bool CreatePictures(void);
bool CreateRadioButtons(void);
bool CreateArrow(CButton &button_obj,const int index);
//---
public:
//--- >72@0I05B C:070B5;8 =0 A>AB02=K5 M;5<5=BK
CButtonsGroup *GetRadioButtonsPointer(void) { return(::GetPointer(m_radio_buttons)); }
CButton *GetLeftArrowPointer(void) { return(::GetPointer(m_left_arrow)); }
CButton *GetRightArrowPointer(void) { return(::GetPointer(m_right_arrow)); }
CPicture *GetPicturePointer(const uint index);
//--- BABC?K 4;O :=>?>:-AB@5;>:
void ArrowsXGap(const int x_gap) { m_arrows_x_gap=x_gap; }
void ArrowsYGap(const int y_gap) { m_arrows_y_gap=y_gap; }
//--- (1) >72@0I05B :>;8G5AB2> :0@B8=>:, (2) >BABC? 4;O :0@B8=>: ?> >A8 Y
int PicturesTotal(void) const { return(::ArraySize(m_pictures)); }
void PictureYGap(const int y_gap) { m_pictures_y_gap=y_gap; }
//--- (1) BABC?K @048>-:=>?>:, (2) @0AAB>O=85 <564C @048>-:=>?:0<8
void RadioButtonsXGap(const int x_gap) { m_radio_buttons_x_gap=x_gap; }
void RadioButtonsYGap(const int y_gap) { m_radio_buttons_y_gap=y_gap; }
void RadioButtonsXOffset(const int x_offset) { m_radio_buttons_x_offset=x_offset; }
//--- >102;O5B :0@B8=:C
void AddPicture(const string file_path="");
//--- 5@5:;NG05B :0@B8=:C ?> C:070==><C 8=45:AC
void SelectPicture(const int index);
//---
public:
//--- 1@01>BG8: A>1KB89 3@0D8:0
virtual void OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- >:070BL, C40;8BL
virtual void Show(void);
virtual void Delete(void);
//--- 8AC5B M;5<5=B
virtual void Draw(void);
//---
private:
//--- 1@01>B:0 =060B8O =0 @048>-:=>?:C
bool OnClickRadioButton(const string clicked_object,const int id,const int index);
//--- 1@01>B:0 =060B8O =0 ;52>9 :=>?:C
bool OnClickLeftArrow(const string clicked_object,const int id,const int index);
//--- 1@01>B:0 =060B8O =0 ?@02>9 :=>?:C
bool OnClickRightArrow(const string clicked_object,const int id,const int index);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CPicturesSlider::CPicturesSlider(void) : m_default_path("Images\\EasyAndFastGUI\\Icons\\bmp64\\no_image.bmp"),
m_arrows_x_gap(2),
m_arrows_y_gap(2),
m_radio_button_width(18),
m_radio_buttons_x_gap(25),
m_radio_buttons_y_gap(1),
m_radio_buttons_x_offset(20),
m_pictures_y_gap(25)
{
//--- !>E@0=8< 8<O :;0AA0 M;5<5=B0 2 107>2>< :;0AA5
CElementBase::ClassName(CLASS_NAME);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CPicturesSlider::~CPicturesSlider(void)
{
}
//+------------------------------------------------------------------+
//| 1@01>BG8: A>1KB89 |
//+------------------------------------------------------------------+
void CPicturesSlider::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
//--- 1@01>B:0 A>1KB8O =060B8O ;52>9 :=>?:8 <KH8 =0 >1J5:B5
if(id==CHARTEVENT_CUSTOM+ON_CLICK_BUTTON)
{
//--- 060B85 =0 @048>-:=>?:5
if(OnClickRadioButton(sparam,(int)lparam,(int)dparam))
return;
//--- A;8 =060B85 =0 :=>?:0E-AB@5;:0E A;0945@0, ?5@5:;NG8BL :0@B8=:C
if(OnClickLeftArrow(sparam,(int)lparam,(int)dparam))
return;
if(OnClickRightArrow(sparam,(int)lparam,(int)dparam))
return;
//---
return;
}
}
//+------------------------------------------------------------------+
//| !>740QB M;5<5=B |
//+------------------------------------------------------------------+
bool CPicturesSlider::CreatePicturesSlider(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(!CreateCanvas())
return(false);
if(!CreatePictures())
return(false);
if(!CreateRadioButtons())
return(false);
if(!CreateArrow(m_left_arrow,0))
return(false);
if(!CreateArrow(m_right_arrow,1))
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+
//| =8F80;870F8O A2>9AB2 |
//+------------------------------------------------------------------+
void CPicturesSlider::InitializeProperties(const int x_gap,const int y_gap)
{
m_x =CElement::CalculateX(x_gap);
m_y =CElement::CalculateY(y_gap);
m_x_size =(m_x_size<1)? 300 : m_x_size;
m_y_size =(m_y_size<1)? 300 : m_y_size;
//--- !2>9AB20 ?> C<>;G0=8N
m_back_color =(m_back_color!=clrNONE)? m_back_color : m_main.BackColor();
m_border_color =(m_border_color!=clrNONE)? m_border_color : m_main.BackColor();
//--- BABC?K >B :@09=59 B>G:8
CElementBase::XGap(x_gap);
CElementBase::YGap(y_gap);
}
//+------------------------------------------------------------------+
//| !>740QB >1J5:B 4;O @8A>20=8O |
//+------------------------------------------------------------------+
bool CPicturesSlider::CreateCanvas(void)
{
//--- $>@<8@>20=85 8<5=8 >1J5:B0
string name=CElementBase::ElementName("pictures_slider");
//--- !>740=85 >1J5:B0
if(!CElement::CreateCanvas(name,m_x,m_y,m_x_size,m_y_size))
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+
//| !>740QB 3@C??C :0@B8=>: |
//+------------------------------------------------------------------+
bool CPicturesSlider::CreatePictures(void)
{
//--- >;CG8< :>;8G5AB2> :0@B8=>:
int pictures_total=PicturesTotal();
//--- A;8 =5B =8 >4=>9 :0@B8=:8 2 3@C??5, A>>1I8BL >1 MB><
if(pictures_total<1)
{
::Print(__FUNCTION__," > K7>2 MB>3> <5B>40 =C6=> >ACI5AB2;OBL, "
":>340 2 3@C??5 5ABL E>BO 1K >4=0 :0@B8=:0! >A?>;L7C9B5AL <5B>4>< CPicturesSlider::AddPicture()");
return(false);
}
//--- >>@48=0BK
uint x=0,y=m_pictures_y_gap;
//--- 07<5@K
uint x_size=0,y_size=0;
//--- 0AA82 4;O 87>1@065=8O
uint image_data[];
//---
for(int i=0; i<pictures_total; i++)
{
//--- !>E@0=8< C:070B5;L =0 >:=>
m_pictures[i].MainPointer(this);
//--- @>G8B0BL 40==K5 87>1@065=8O
if(!::ResourceReadImage("::"+m_file_path[i],image_data,x_size,y_size))
{
::Print(__FUNCTION__," > H81:0 ?@8 GB5=88 87>1@065=8O ("+m_file_path[i]+"): ",::GetLastError());
return(false);
}
//--- 0AAG8B0BL >BABC?
x=(m_x_size>>1)-(x_size>>1);
//--- !2>9AB20
m_pictures[i].Index(i);
m_pictures[i].XSize(x_size);
m_pictures[i].YSize(y_size);
m_pictures[i].NamePart("picture_slider");
m_pictures[i].IconFile(m_file_path[i]);
m_pictures[i].IconFileLocked(m_file_path[i]);
//--- !>740=85 :=>?:8
if(!m_pictures[i].CreatePicture(x,y))
return(false);
//--- >1028BL M;5<5=B 2 <0AA82
CElement::AddToArray(m_pictures[i]);
}
return(true);
}
//+------------------------------------------------------------------+
//| !>740QB 3@C??C @048>-:=>?>: |
//+------------------------------------------------------------------+
bool CPicturesSlider::CreateRadioButtons(void)
{
//--- !>E@0=8< C:070B5;L =0 @>48B5;LA:89 M;5<5=B
m_radio_buttons.MainPointer(this);
//--- >>@48=0BK
int x=m_radio_buttons_x_gap,y=m_radio_buttons_y_gap;
//--- >;8G5AB2> :0@B8=>:
int pictures_total=PicturesTotal();
//--- !2>9AB20
int buttons_x_offset[];
//--- #AB0=>28< @07<5@ <0AA820<
::ArrayResize(buttons_x_offset,pictures_total);
//--- BABC?K <564C @048>-:=>?:0<8
for(int i=0; i<pictures_total; i++)
buttons_x_offset[i]=(i>0)? buttons_x_offset[i-1]+m_radio_buttons_x_offset : 0;
//---
m_radio_buttons.NamePart("radio_button");
m_radio_buttons.RadioButtonsMode(true);
m_radio_buttons.RadioButtonsStyle(true);
//--- >1028< :=>?:8 2 3@C??C
for(int i=0; i<pictures_total; i++)
m_radio_buttons.AddButton(buttons_x_offset[i],0,"",m_radio_button_width);
//--- !>740BL 3@C??C :=>?>:
if(!m_radio_buttons.CreateButtonsGroup(x,y))
return(false);
//--- >:065< :0@B8=:C ?> 2K45;5==>9 @048>-:=>?:5
SelectPicture(1);
//--- >1028BL M;5<5=B 2 <0AA82
CElement::AddToArray(m_radio_buttons);
return(true);
}
//+------------------------------------------------------------------+
//| !>740QB :=>?:C A> AB@5;:>9 |
//+------------------------------------------------------------------+
//#resource "\\Images\\EasyAndFastGUI\\Controls\\left_thin_black.bmp"
//#resource "\\Images\\EasyAndFastGUI\\Controls\\right_thin_black.bmp"
//---
bool CPicturesSlider::CreateArrow(CButton &button_obj,const int index)
{
//--- !>E@0=8< C:070B5;L =0 3;02=K9 M;5<5=B
button_obj.MainPointer(this);
//--- >>@48=0BK
int x =(index<1)? m_arrows_x_gap : m_arrows_x_gap+16;
int y =m_arrows_y_gap;
//--- #AB0=>28< A2>9AB20 ?5@54 A>740=85<
button_obj.Index(index);
button_obj.XSize(16);
button_obj.YSize(16);
//--- /@;K:8 4;O :=>?>:
if(index<1)
{
button_obj.IconFile(RESOURCE_LEFT_THIN_BLACK);
button_obj.IconFileLocked(RESOURCE_LEFT_THIN_BLACK);
}
else
{
button_obj.IconFile(RESOURCE_RIGHT_THIN_BLACK);
button_obj.IconFileLocked(RESOURCE_RIGHT_THIN_BLACK);
button_obj.AnchorRightWindowSide(true);
}
//--- !>74048< M;5<5=B C?@02;5=8O
if(!button_obj.CreateButton("",x,y))
return(false);
//--- >1028BL M;5<5=B 2 <0AA82
CElement::AddToArray(button_obj);
return(true);
}
//+------------------------------------------------------------------+
//| >102;O5B :0@B8=:C |
//+------------------------------------------------------------------+
CPicture *CPicturesSlider::GetPicturePointer(const uint index)
{
uint array_size=PicturesTotal();
//--- @>25@:0 @07<5@0 <0AA820 >1J5:B>2
if(array_size<1)
{
Print(__FUNCTION__," >  3@C??5 =5B =8 >4=>3> M;5<5=B0!");
return(NULL);
}
//--- >@@5:B8@>2:0 2 A;CG05 2KE>40 87 480?07>=0
uint i=(index>=array_size)? array_size-1 : index;
//--- 5@=CBL C:070B5;L >1J5:B0
return(::GetPointer(m_pictures[i]));
}
//+------------------------------------------------------------------+
//| >102;O5B :0@B8=:C |
//+------------------------------------------------------------------+
void CPicturesSlider::AddPicture(const string file_path="")
{
//--- #25;8G8< @07<5@ <0AA82>2 =0 >48= M;5<5=B
int array_size=::ArraySize(m_pictures);
int new_size=array_size+1;
::ArrayResize(m_pictures,new_size);
::ArrayResize(m_file_path,new_size);
//--- !>E@0=8< 7=0G5=8O ?5@540==KE ?0@0<5B@>2
m_file_path[array_size]=(file_path=="")? m_default_path : file_path;
}
//+------------------------------------------------------------------+
//| #:07K205B, :0:0O :0@B8=:0 4>;6=0 1KBL ?>:070=0 |
//+------------------------------------------------------------------+
void CPicturesSlider::SelectPicture(const int index)
{
//--- >;CG8< :>;8G5AB2> :0@B8=>:
int pictures_total=PicturesTotal();
//--- A;8 =5B =8 >4=>9 :0@B8=:8 2 3@C??5, A>>1I8BL >1 MB><
if(pictures_total<1)
{
::Print(__FUNCTION__," > K7>2 MB>3> <5B>40 =C6=> >ACI5AB2;OBL, "
":>340 2 3@C??5 5ABL E>BO 1K >4=0 :0@B8=:0! >A?>;L7C9B5AL <5B>4>< CPicturesSlider::AddPicture()");
return;
}
//--- !:>@@5:B8@>20BL 7=0G5=85 8=45:A0, 5A;8 2KE>48B 87 480?07>=0
uint correct_index=(index>=pictures_total)? pictures_total-1 :(index<0)? 0 : index;
//--- K45;8BL @048>-:=>?:C ?> MB><C 8=45:AC
m_radio_buttons.SelectButton(correct_index);
//--- 5@5:;NG8BL :0@B8=:C
for(int i=0; i<pictures_total; i++)
{
if(i==correct_index)
m_pictures[i].Show();
else
m_pictures[i].Hide();
}
}
//+------------------------------------------------------------------+
//| >:070BL |
//+------------------------------------------------------------------+
void CPicturesSlider::Show(void)
{
CElement::Show();
SelectPicture(m_radio_buttons.SelectedButtonIndex());
}
//+------------------------------------------------------------------+
//| #40;5=85 |
//+------------------------------------------------------------------+
void CPicturesSlider::Delete(void)
{
CElement::Delete();
//--- A2>1>645=85 <0AA82>2 M;5<5=B0
::ArrayFree(m_pictures);
}
//+------------------------------------------------------------------+
//| 060B85 =0 @048>-:=>?:C |
//+------------------------------------------------------------------+
bool CPicturesSlider::OnClickRadioButton(const string clicked_object,const int id,const int index)
{
//--- K945<, 5A;8 =060B85 1K;> =5 =0 :=>?:5
if(::StringFind(clicked_object,m_radio_buttons.NamePart(),0)<0)
return(false);
//--- K9B8, 5A;8 (1) 845=B8D8:0B>@K =5 A>2?040NB 8;8 (2) M;5<5=B 701;>:8@>20=
if(id!=CElementBase::Id() || CElementBase::IsLocked())
return(false);
//--- K9B8, 5A;8 8=45:A A>2?0405B
if(index==m_radio_buttons.SelectedButtonIndex())
return(true);
//--- K1@0BL :0@B8=:C
SelectPicture(index);
//--- 5@5@8A>20BL M;5<5=B
m_radio_buttons.Update(true);
return(true);
}
//+------------------------------------------------------------------+
//| 060B85 =0 ;52CN :=>?:C |
//+------------------------------------------------------------------+
bool CPicturesSlider::OnClickLeftArrow(const string clicked_object,const int id,const int index)
{
//--- K945<, 5A;8 =060B85 1K;> =5 =0 :=>?:5
if(::StringFind(clicked_object,m_left_arrow.NamePart(),0)<0)
return(false);
//--- K9B8, 5A;8 (1) 845=B8D8:0B>@K =5 A>2?040NB 8;8 (2) M;5<5=B 701;>:8@>20=
if(id!=CElementBase::Id() || index!=m_left_arrow.Index() || CElementBase::IsLocked())
return(false);
//--- >;CG8< B5:CI89 8=45:A 2K45;5==>9 @048>-:=>?:8
int selected_radio_button=m_radio_buttons.SelectedButtonIndex();
//--- 5@5:;NG5=85 :0@B8=:8
SelectPicture(--selected_radio_button);
//--- 5@5@8A>20BL @048>-:=>?:8
m_radio_buttons.Update(true);
//--- B?@028< A>>1I5=85 >1 MB><
::EventChartCustom(m_chart_id,ON_CLICK_BUTTON,CElementBase::Id(),CElementBase::Index(),"");
return(true);
}
//+------------------------------------------------------------------+
//| 060B85 =0 ?@02CN :=>?:C |
//+------------------------------------------------------------------+
bool CPicturesSlider::OnClickRightArrow(const string clicked_object,const int id,const int index)
{
//--- K945<, 5A;8 =060B85 1K;> =5 =0 :=>?:5
if(::StringFind(clicked_object,m_right_arrow.NamePart(),0)<0)
return(false);
//--- K9B8, 5A;8 (1) 845=B8D8:0B>@K =5 A>2?040NB 8;8 (2) M;5<5=B 701;>:8@>20=
if(id!=CElementBase::Id() || index!=m_right_arrow.Index() || CElementBase::IsLocked())
return(false);
//--- >;CG8< B5:CI89 8=45:A 2K45;5==>9 @048>-:=>?:8
int selected_radio_button=m_radio_buttons.SelectedButtonIndex();
//--- 5@5:;NG5=85 :0@B8=:8
SelectPicture(++selected_radio_button);
//--- 5@5@8A>20BL @048>-:=>?:8
m_radio_buttons.Update(true);
//--- B?@028< A>>1I5=85 >1 MB><
::EventChartCustom(m_chart_id,ON_CLICK_BUTTON,CElementBase::Id(),CElementBase::Index(),"");
return(true);
}
//+------------------------------------------------------------------+
//| 8AC5B M;5<5=B |
//+------------------------------------------------------------------+
void CPicturesSlider::Draw(void)
{
//--- 0@8A>20BL D>=
CElement::DrawBackground();
//--- 0@8A>20BL @0<:C
CElement::DrawBorder();
}
//+------------------------------------------------------------------+