EasyAndFastMod/Controls/SplitButton.mqh

320 lines
27 KiB
MQL5
Raw Permalink Normal View History

2026-01-15 07:23:17 -05:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| SplitButton.mqh |
//| Copyright 2015, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "..\Element.mqh"
#include "Button.mqh"
#include "ContextMenu.mqh"
//+------------------------------------------------------------------+
//| ;0AA 4;O A>740=8O A42>5==>9 :=>?:8 |
//+------------------------------------------------------------------+
class CSplitButton : public CElement
{
private:
//--- 1J5:BK 4;O A>740=8O :=>?:8
CButton m_button;
CButton m_drop_button;
CContextMenu m_drop_menu;
//--- !>AB>O=85 :>=B5:AB=>3> <5=N
bool m_drop_menu_state;
//---
public:
CSplitButton(void);
~CSplitButton(void);
//--- 5B>4K 4;O A>740=8O :=>?:8
bool CreateSplitButton(const string text,const int x_gap,const int y_gap);
//---
private:
void InitializeProperties(const string text,const int x_gap,const int y_gap);
bool CreateButton(void);
bool CreateDropButton(void);
bool CreateDropMenu(void);
//---
public:
//--- (1) ?>;CG5=85 C:070B5;O :>=B5:AB=>3> <5=N, (2) >1I55 A>AB>O=85 :=>?:8 (4>ABC?5=/701;>:8@>20=)
CButton *GetButtonPointer(void) { return(::GetPointer(m_button)); }
CButton *GetDropButtonPointer(void) { return(::GetPointer(m_drop_button)); }
CContextMenu *GetContextMenuPointer(void) { return(::GetPointer(m_drop_menu)); }
//--- >102;O5B ?C=:B <5=N A C:070==K<8 A2>9AB20<8 4> A>740=8O :>=B5:AB=>3> <5=N
void AddItem(const string text,const string path_bmp_on,const string path_bmp_off);
//--- >102;O5B @0745;8B5;L=CN ;8=8N ?>A;5 C:070==>3> ?C=:B0 4> A>740=8O :>=B5:AB=>3> <5=N
void AddSeparateLine(const int item_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);
//---
private:
//--- 1@01>B:0 =060B8O =0 :=>?:C
bool OnClickButton(const string pressed_object,const int id,const int index);
//--- 1@01>B:0 =060B8O =0 :=>?:C A 2K?040NI8< <5=N
bool OnClickDropButton(const string pressed_object,const int id,const int index);
//--- !:@K205B 2K?040NI55 <5=N
void HideDropDownMenu(void);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSplitButton::CSplitButton(void) : m_drop_menu_state(false)
{
//--- !>E@0=8< 8<O :;0AA0 M;5<5=B0 2 107>2>< :;0AA5
CElementBase::ClassName(CLASS_NAME);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CSplitButton::~CSplitButton(void)
{
}
//+------------------------------------------------------------------+
//| 1@01>BG8: A>1KB89 |
//+------------------------------------------------------------------+
void CSplitButton::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)
{
//--- @>25@:0 D>:CA0 =04 M;5<5=B0<8
m_drop_button.MouseFocus(m_mouse.X()>m_drop_button.X() && m_mouse.X()<m_drop_button.X2() &&
m_mouse.Y()>m_drop_button.Y() && m_mouse.Y()<m_drop_button.Y2());
//--- =5 >1;0AB8 M;5<5=B0 8 A =060B>9 :=>?:>9 <KH8
if(!CElementBase::MouseFocus() && m_mouse.LeftButtonState())
{
//--- K9B8, 5A;8 D>:CA 2 :>=B5:AB=>< <5=N
if(m_drop_menu.MouseFocus())
return;
//--- !:@KBL 2K?040NI55 <5=N
HideDropDownMenu();
return;
}
return;
}
//--- 1@01>B:0 A>1KB8O =060B8O =0 ?C=:B5 A2>1>4=>3> <5=N
if(id==CHARTEVENT_CUSTOM+ON_CLICK_FREEMENU_ITEM)
{
//--- K9B8, 5A;8 845=B8D8:0B>@K =5 A>2?040NB
if(CElementBase::Id()!=lparam)
return;
//--- !:@KBL 2K?040NI55 <5=N
HideDropDownMenu();
//--- B?@028< A>>1I5=85
::EventChartCustom(m_chart_id,ON_CLICK_CONTEXTMENU_ITEM,lparam,dparam,sparam);
return;
}
//--- 1@01>B:0 A>1KB8O =060B8O ;52>9 :=>?:8 <KH8 =0 M;5<5=B5
if(id==CHARTEVENT_CUSTOM+ON_CLICK_BUTTON)
{
//--- 060B85 =0 >A=>2=>9 :=>?:5
if(OnClickButton(sparam,(int)lparam,(int)dparam))
return;
//--- 060B85 =0 :=>?:5 A 2K?040NI8< <5=N
if(OnClickDropButton(sparam,(int)lparam,(int)dparam))
return;
}
}
//+------------------------------------------------------------------+
//| !>740QB M;5<5=B "=>?:0" |
//+------------------------------------------------------------------+
bool CSplitButton::CreateSplitButton(const string text,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(text,x_gap,y_gap);
//--- !>740=85 :=>?:8
if(!CreateButton())
return(false);
if(!CreateDropButton())
return(false);
if(!CreateDropMenu())
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+
//| =8F80;870F8O A2>9AB2 |
//+------------------------------------------------------------------+
void CSplitButton::InitializeProperties(const string text,const int x_gap,const int y_gap)
{
m_x =CElement::CalculateX(x_gap);
m_y =CElement::CalculateY(y_gap);
m_label_text =text;
m_x_size =(m_x_size<1)? 80 : m_x_size;
m_y_size =(m_y_size<1)? 20 : m_y_size;
//--- BABC?K >B :@09=59 B>G:8
CElementBase::XGap(x_gap);
CElementBase::YGap(y_gap);
//--- @8>@8B5B, :0: C 3;02=>3> M;5<5=B0, B0: :0: M;5<5=B =5 8<55B A2>59 >1;0AB8 4;O =060B8O
CElement::Z_Order(m_main.Z_Order());
}
//+------------------------------------------------------------------+
//| !>740QB :=>?:C |
//+------------------------------------------------------------------+
bool CSplitButton::CreateButton(void)
{
//--- !>E@0=8< C:070B5;L =0 @>48B5;LA:89 M;5<5=B
m_button.MainPointer(this);
//--- 07<5@K
int x_size=m_x_size-18;
//--- >>@48=0BK
int x=0,y=0;
//--- BABC?K 4;O :0@B8=:8
int icon_x_gap =(m_button.IconXGap()<1)? 3 : m_button.IconXGap();
int icon_y_gap =(m_button.IconYGap()<1)? 3 : m_button.IconYGap();
//--- !2>9AB20
m_button.NamePart("split_button");
m_button.Index(0);
m_button.Alpha(m_alpha);
m_button.XSize(x_size);
m_button.YSize(m_y_size);
m_button.IconXGap(icon_x_gap);
m_button.IconYGap(icon_y_gap);
m_button.IconFile(IconFile());
m_button.IconFileLocked(IconFileLocked());
//--- !>74048< M;5<5=B C?@02;5=8O
if(!m_button.CreateButton(m_label_text,x,y))
return(false);
//--- >1028BL M;5<5=B 2 <0AA82
CElement::AddToArray(m_button);
return(true);
}
//+------------------------------------------------------------------+
//| !>740QB :=>?:C 4;O 2K7>20 :>=B5:AB=>3> <5=N |
//+------------------------------------------------------------------+
bool CSplitButton::CreateDropButton(void)
{
//--- !>E@0=8< C:070B5;L =0 @>48B5;LA:89 M;5<5=B
m_drop_button.MainPointer(this);
//--- 07<5@K
int x_size=18;
//--- >>@48=0BK
int x=m_button.XSize()-1,y=0;
//--- BABC?K 4;O :0@B8=:8
int icon_x_gap =(m_drop_button.IconXGap()<1)? 1 : m_drop_button.IconXGap();
int icon_y_gap =(m_drop_button.IconYGap()<1)? 3 : m_drop_button.IconYGap();
//--- #AB0=>28< A2>9AB20 ?5@54 A>740=85<
m_drop_button.NamePart("split_button");
m_drop_button.Index(1);
m_drop_button.Alpha(m_alpha);
m_drop_button.TwoState(true);
m_drop_button.XSize(x_size);
m_drop_button.YSize(m_y_size);
m_drop_button.IconXGap(icon_x_gap);
m_drop_button.IconYGap(icon_y_gap);
m_drop_button.IconFile(RESOURCE_DOWN_THIN_BLACK);
m_drop_button.IconFileLocked(RESOURCE_DOWN_THIN_BLACK);
m_drop_button.CElement::IconFilePressed(RESOURCE_UP_THIN_BLACK);
m_drop_button.CElement::IconFilePressedLocked(RESOURCE_UP_THIN_BLACK);
//--- !>74048< M;5<5=B C?@02;5=8O
if(!m_drop_button.CreateButton("",x,y))
return(false);
//--- >1028BL M;5<5=B 2 <0AA82
CElement::AddToArray(m_drop_button);
return(true);
}
//+------------------------------------------------------------------+
//| !>740QB 2K?040NI55 <5=N |
//+------------------------------------------------------------------+
bool CSplitButton::CreateDropMenu(void)
{
//--- !>E@0=8< C:070B5;L =0 3;02=K9 M;5<5=B
m_drop_menu.MainPointer(this);
//--- !2>1>4=>5 :>=B5:AB=>5 <5=N
m_drop_menu.FreeContextMenu(true);
//--- >>@48=0BK
int x=0,y=m_y_size;
//--- #AB0=>28< A2>9AB20
m_drop_menu.XSize((m_drop_menu.XSize()>0)? m_drop_menu.XSize() : m_x_size-1);
//--- #AB0=>28< :>=B5:AB=>5 <5=N
if(!m_drop_menu.CreateContextMenu(x,y))
return(false);
//--- >1028BL M;5<5=B 2 <0AA82
CElement::AddToArray(m_drop_menu);
return(true);
}
//+------------------------------------------------------------------+
//| >102;O5B ?C=:B <5=N |
//+------------------------------------------------------------------+
void CSplitButton::AddItem(const string text,const string path_bmp_on,const string path_bmp_off)
{
m_drop_menu.AddItem(text,path_bmp_on,path_bmp_off,MI_SIMPLE);
}
//+------------------------------------------------------------------+
//| >102;O5B @0745;8B5;L=CN ;8=8N |
//+------------------------------------------------------------------+
void CSplitButton::AddSeparateLine(const int item_index)
{
m_drop_menu.AddSeparateLine(item_index);
}
//+------------------------------------------------------------------+
//| 060B85 =0 :=>?:C |
//+------------------------------------------------------------------+
bool CSplitButton::OnClickButton(const string pressed_object,const int id,const int index)
{
//--- K945<, 5A;8 =060B85 1K;> =5 =0 :=>?:5
if(::StringFind(pressed_object,"split_button")<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_button.Index() || CElementBase::IsLocked())
return(false);
//--- !:@>5< <5=N
HideDropDownMenu();
//--- B?@028< A>>1I5=85 >1 MB><
::EventChartCustom(m_chart_id,ON_CLICK_BUTTON,CElementBase::Id(),CElementBase::Index(),"");
return(true);
}
//+------------------------------------------------------------------+
//| 060B85 =0 :=>?:C A 2K?040NI8< <5=N |
//+------------------------------------------------------------------+
bool CSplitButton::OnClickDropButton(const string pressed_object,const int id,const int index)
{
//--- K945<, 5A;8 =060B85 1K;> =5 =0 :=>?:5
if(::StringFind(pressed_object,"split_button")<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_drop_button.Index() || CElementBase::IsLocked())
return(false);
//--- A;8 A?8A>: >B:@KB, A:@>5< 53>
if(m_drop_menu_state)
{
m_drop_menu_state=false;
m_drop_menu.Hide();
//--- B?@028< A>>1I5=85 =0 >?@545;5=85 4>ABC?=KE M;5<5=B>2
::EventChartCustom(m_chart_id,ON_SET_AVAILABLE,CElementBase::Id(),1,"");
}
//--- A;8 A?8A>: A:@KB, >B:@>5< 53>
else
{
m_drop_menu_state=true;
m_drop_menu.Show();
//--- B?@028< A>>1I5=85 =0 >?@545;5=85 4>ABC?=KE M;5<5=B>2
::EventChartCustom(m_chart_id,ON_SET_AVAILABLE,CElementBase::Id(),0,"");
}
//--- B?@028< A>>1I5=85 >1 87<5=5=88 2 3@0D8G5A:>< 8=B5@D59A5
::EventChartCustom(m_chart_id,ON_CHANGE_GUI,CElementBase::Id(),0.0,"");
return(true);
}
//+------------------------------------------------------------------+
//| !:@K205B 2K?040NI55 <5=N |
//+------------------------------------------------------------------+
void CSplitButton::HideDropDownMenu(void)
{
//--- !:@KBL <5=N 8 CAB0=>28BL A>>B25BAB2CNI85 ?@87=0:8
m_drop_menu.Hide();
m_drop_menu_state=false;
//--- B60BL :=>?:C, 5A;8 =060B0
if(m_drop_button.IsPressed())
{
m_drop_button.IsPressed(false);
m_drop_button.Update(true);
//--- B?@028< A>>1I5=85 =0 >?@545;5=85 4>ABC?=KE M;5<5=B>2
::EventChartCustom(m_chart_id,ON_SET_AVAILABLE,CElementBase::Id(),1,"");
//--- B?@028< A>>1I5=85 >1 87<5=5=88 2 3@0D8G5A:>< 8=B5@D59A5
::EventChartCustom(m_chart_id,ON_CHANGE_GUI,CElementBase::Id(),0.0,"");
}
}
//+------------------------------------------------------------------+