EasyAndFastMod/Controls/MenuItem.mqh

330 lines
28 KiB
MQL5
Raw Permalink Normal View History

2026-01-15 07:23:17 -05:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| MenuItem.mqh |
//| Copyright 2015, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "..\Element.mqh"
#include "Button.mqh"
class CContextMenu;
//+------------------------------------------------------------------+
//| ;0AA A>740=8O ?C=:B0 <5=N |
//+------------------------------------------------------------------+
class CMenuItem : public CButton
{
private:
//--- #:070B5;L =0 ?@54K4CI89 C75;
CMenuItem *m_prev_node;
//--- #:070B5;L =0 ?@82O70==>5 :>=B5:AB=>5 <5=N
CContextMenu *m_context_menu;
//--- "8? ?C=:B0 <5=N
ENUM_TYPE_MENU_ITEM m_type_menu_item;
//--- !2>9AB20 ?@87=0:0 :>=B5:AB=>3> <5=N
bool m_show_right_arrow;
int m_arrow_x_gap;
//--- !>AB>O=85 G5:1>:A0
bool m_checkbox_state;
//--- !>AB>O=85 @048>-:=>?:8 8 5Q 845=B8D8:0B>@
bool m_radiobutton_state;
int m_radiobutton_id;
//---
public:
CMenuItem(void);
~CMenuItem(void);
//--- 5B>4K 4;O A>740=8O ?C=:B0 <5=N
bool CreateMenuItem(const string text,const int x_gap,const int y_gap);
//---
public:
//--- (1) >;CG5=85 8 (2) A>E@0=5=85 C:070B5;O ?@54K4CI53> C7;0
void GetPrevNodePointer(CMenuItem &object) { m_prev_node=::GetPointer(object); }
CMenuItem *GetPrevNodePointer(void) const { return(m_prev_node); }
void GetContextMenuPointer(CContextMenu &object) { m_context_menu=::GetPointer(object); }
CContextMenu *GetContextMenuPointer(void) const { return(m_context_menu); }
//--- (1) #AB0=>2:0 8 ?>;CG5=85 B8?0, (2) =><5@ 8=45:A0
void TypeMenuItem(const ENUM_TYPE_MENU_ITEM type) { m_type_menu_item=type; }
ENUM_TYPE_MENU_ITEM TypeMenuItem(void) const { return(m_type_menu_item); }
//--- (1) B>1@065=85 ?@87=0:0 =0;8G8O :>=B5:AB=>3> <5=N, (2) >1I55 A>AB>O=85 ?C=:B0-G5:1>:A0
void ShowRightArrow(const bool flag) { m_show_right_arrow=flag; }
bool CheckBoxState(void) const { return(m_checkbox_state); }
void CheckBoxState(const bool state);
//--- (1) 45=B8D8:0B>@ @048>-?C=:B0, (2) A>AB>O=85 @048>-?C=:B0
void RadioButtonID(const int id) { m_radiobutton_id=id; }
int RadioButtonID(void) const { return(m_radiobutton_id); }
bool RadioButtonState(void) const { return(m_radiobutton_state); }
void RadioButtonState(const bool state);
//---
public:
//--- 1@01>BG8: A>1KB89 3@0D8:0
virtual void OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- #?@02;5=85
virtual void Show(void);
virtual void Hide(void);
//--- 8AC5B M;5<5=B
virtual void Draw(void);
//---
private:
//--- 060B85 =0 ?C=:B5 <5=N
bool OnClickMenuItem(const string pressed_object,const int id,const int index);
//--- 8AC5B :0@B8=:C
virtual void DrawImage(void);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CMenuItem::CMenuItem(void) : m_type_menu_item(MI_SIMPLE),
m_checkbox_state(true),
m_radiobutton_id(0),
m_radiobutton_state(false),
m_show_right_arrow(true),
m_arrow_x_gap(18)
{
//--- !>E@0=8< 8<O :;0AA0 M;5<5=B0 2 107>2>< :;0AA5
CElementBase::ClassName(CLASS_NAME);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CMenuItem::~CMenuItem(void)
{
}
//+------------------------------------------------------------------+
//| 1@01>BG8: A>1KB89 |
//+------------------------------------------------------------------+
void CMenuItem::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
//--- 1@01>B0BL A>1KB85 2 107>2>< :;0AA5
CButton::OnEvent(id,lparam,dparam,sparam);
//--- 1@01>B:0 A>1KB8O =060B8O ;52>9 :=>?:8 <KH8 =0 M;5<5=B5
if(id==CHARTEVENT_CUSTOM+ON_CLICK_BUTTON)
{
if(OnClickMenuItem(sparam,(uint)lparam,(uint)dparam))
return;
//---
return;
}
}
//+------------------------------------------------------------------+
//| !>740QB M;5<5=B "C=:B <5=N" |
//+------------------------------------------------------------------+
bool CMenuItem::CreateMenuItem(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);
//--- A;8 C:070B5;O =0 ?@54K4CI89 C75; =5B, B> ?C=:B =5 O2;O5BAO G0ABLN :>=B5:AB=>3> <5=N
if(::CheckPointer(m_prev_node)==POINTER_INVALID)
{
//--- K9B8, 5A;8 CAB0=>2;5==K9 B8? =5 A>>B25BAB2C5B
if(m_type_menu_item!=MI_SIMPLE && m_type_menu_item!=MI_HAS_CONTEXT_MENU)
{
::Print(__FUNCTION__," > "8? =57028A8<>3> ?C=:B0 <5=N <>65B 1KBL B>;L:> MI_SIMPLE 8;8 MI_HAS_CONTEXT_MENU, ",
"B> 5ABL, A =0;8G85< :>=B5:AB=>3> <5=N.\n",
__FUNCTION__," > #AB0=>28BL B8? ?C=:B0 <5=N <>6=> A ?><>ILN <5B>40 CMenuItem::TypeMenuItem()");
return(false);
}
}
//--- ?@545;8< O@;K:8, 5A;8 ?C=:B 8<55B 2K?040NI55 <5=N
if(m_type_menu_item==MI_HAS_CONTEXT_MENU)
{
CButton::TwoState(true);
//--- A;8 =C6=> >B>1@060BL AB@5;:C, :0: ?@87=0: =0;8G8O :>=B5:AB=>3> <5=N
if(m_show_right_arrow)
{
if(CButton::ImagesGroupTotal()<2)
{
CButton::AddImagesGroup(CElementBase::XSize()-m_arrow_x_gap,CElement::IconYGap());
CButton::AddImage(1,RESOURCE_ARROW_RIGHT_BLACK);
CButton::AddImage(1,RESOURCE_ARROW_RIGHT_WHITE);
}
}
}
//--- A;8 MB> G5:1>:A
if(m_type_menu_item==MI_CHECKBOX)
{
//--- 7>1@065=8O ?> C<>;G0=8N
CButton::SetImage(0,0,RESOURCE_CHECKBOX_MINI_BLACK);
CButton::SetImage(0,1,RESOURCE_CHECKBOX_MINI_WHITE);
CButton::AddImage(0,INT_MAX);
}
//--- A;8 MB> @048>-?C=:B
else if(m_type_menu_item==MI_RADIOBUTTON)
{
//--- 7>1@065=8O ?> C<>;G0=8N
CButton::SetImage(0,0,RESOURCE_CHECKBOX_MINI_BLACK);
CButton::SetImage(0,1,RESOURCE_CHECKBOX_MINI_WHITE);
CButton::AddImage(0,INT_MAX);
}
//--- !2>9AB20
CButton::NamePart("menu_item");
//--- !>74048< M;5<5=B C?@02;5=8O
if(!CButton::CreateButton(text,x_gap,y_gap))
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+
//| 7<5=5=85 A>AB>O=8O ?C=:B0 <5=N B8?0 G5:1>:A |
//+------------------------------------------------------------------+
void CMenuItem::CheckBoxState(const bool state)
{
m_checkbox_state=state;
Update(true);
}
//+------------------------------------------------------------------+
//| 7<5=5=85 A>AB>O=8O ?C=:B0 <5=N B8?0 @048>?C=:B |
//+------------------------------------------------------------------+
void CMenuItem::RadioButtonState(const bool state)
{
m_radiobutton_state=state;
Update(true);
}
//+------------------------------------------------------------------+
//| 5;05B 2848<K< ?C=:B <5=N |
//+------------------------------------------------------------------+
void CMenuItem::Show(void)
{
//--- K9B8, 5A;8 M;5<5=B C65 2848<
if(CElementBase::IsVisible())
return;
//--- >:070BL M;5<5=B
CButton::Show();
//--- 1=>28BL ?>;>65=85 >1J5:B>2
Moving();
}
//+------------------------------------------------------------------+
//| !:@K205B ?C=:B <5=N |
//+------------------------------------------------------------------+
void CMenuItem::Hide(void)
{
//--- K9B8, 5A;8 M;5<5=B A:@KB
if(!CElementBase::IsVisible())
return;
//--- !:@KBL M;5<5=B
CButton::Hide();
//--- 1=C;5=85 ?5@5<5==KE
CElementBase::IsVisible(false);
CElementBase::MouseFocus(false);
}
//+------------------------------------------------------------------+
//| 1@01>B:0 =060B8O =0 ?C=:B5 <5=N |
//+------------------------------------------------------------------+
bool CMenuItem::OnClickMenuItem(const string pressed_object,const int id,const int index)
{
//--- K945<, 5A;8 =060B85 1K;> =5 =0 :=>?:5
if(::StringFind(pressed_object,"menu_item")<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!=CElementBase::Index() || CElementBase::IsLocked())
return(false);
//--- A;8 MB>B ?C=:B A>45@68B :>=B5:AB=>5 <5=N
if(m_type_menu_item==MI_HAS_CONTEXT_MENU)
{
if(::CheckPointer(m_context_menu)==POINTER_INVALID)
return(true);
//--- A;8 2K?040NI55 <5=N MB>3> ?C=:B0 =5 0:B828@>20=>
if(!m_context_menu.IsVisible())
{
//--- >:070BL :>=B5:AB=>5 <5=N
m_context_menu.Show();
//--- !>>1I5=85 =0 2>AAB0=>2;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,"");
}
else
{
int is_restore=1;
if(CheckPointer(m_prev_node)!=POINTER_INVALID)
is_restore=0;
//--- !:@KBL :>=B5:AB=>5 <5=N
m_context_menu.Hide();
//--- B?@028< A83=0; 4;O 70:@KB8O :>=B5:AB=KE <5=N, :>B>@K5 40;LH5 MB>3> ?C=:B0
::EventChartCustom(m_chart_id,ON_HIDE_BACK_CONTEXTMENUS,CElementBase::Id(),0,"");
//--- !>>1I5=85 =0 2>AAB0=>2;5=85 4>ABC?=KE M;5<5=B>2
::EventChartCustom(m_chart_id,ON_SET_AVAILABLE,CElementBase::Id(),is_restore,"");
//--- 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,"");
}
}
//--- A;8 MB>B ?C=:B =5 A>45@68B :>=B5:AB=>5 <5=N, => O2;O5BAO G0ABLN :>=B5:AB=>3> <5=N
else
{
//--- @5D8:A A>>1I5=8O A 8<5=5< ?@>3@0<<K
string message=CElementBase::ProgramName();
//--- A;8 MB> G5:1>:A, 87<5=8< 53> A>AB>O=85
if(m_type_menu_item==MI_CHECKBOX)
{
m_checkbox_state=(m_checkbox_state)? false : true;
//--- >1028< 2 A>>1I5=85, GB> MB> G5:1>:A
message+="_checkbox";
}
//--- A;8 MB> @048>-?C=:B, 87<5=8< 53> A>AB>O=85
else if(m_type_menu_item==MI_RADIOBUTTON)
{
m_radiobutton_state=(m_radiobutton_state)? false : true;
//--- >1028< 2 A>>1I5=85, GB> MB> @048>-?C=:B
message+="_radioitem_"+(string)m_radiobutton_id;
}
//--- B60BL :=>?:C
CElementBase::MouseFocus(false);
CElement::Update(true);
//--- B?@028< A>>1I5=85 >1 MB><
::EventChartCustom(m_chart_id,ON_CLICK_MENU_ITEM,CElementBase::Id(),CElementBase::Index(),message);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| 8AC5B M;5<5=B |
//+------------------------------------------------------------------+
void CMenuItem::Draw(void)
{
//--- 0@8A>20BL D>=
CButton::DrawBackground();
//--- 0@8A>20BL @0<:C
CButton::DrawBorder();
//--- 0@8A>20BL :0@B8=:C
if(m_type_menu_item!=MI_SIMPLE)
CMenuItem::DrawImage();
else
CButton::DrawImage();
//--- 0@8A>20BL B5:AB
CElement::DrawText();
}
//+------------------------------------------------------------------+
//| 8AC5B :0@B8=:C |
//+------------------------------------------------------------------+
void CMenuItem::DrawImage(void)
{
//--- ?@545;8< 8=45:A
uint image_index=0;
//---
if(m_type_menu_item==MI_CHECKBOX)
{
image_index=(m_checkbox_state)?(m_mouse_focus)? 1 : 0 : 2;
//--- !>E@0=8BL 8=45:A 2K1@0==>3> 87>1@065=8O
CElement::ChangeImage(0,image_index);
}
else if(m_type_menu_item==MI_RADIOBUTTON)
{
image_index=(m_radiobutton_state)?(m_mouse_focus)? 1 : 0 : 2;
//--- !>E@0=8BL 8=45:A 2K1@0==>3> 87>1@065=8O
CElement::ChangeImage(0,image_index);
}
else if(m_type_menu_item==MI_HAS_CONTEXT_MENU)
{
image_index=(m_mouse_focus || m_is_pressed)? 1 : 0;
//--- !>E@0=8BL 8=45:A 2K1@0==>3> 87>1@065=8O
CElement::ChangeImage(0,0);
CElement::ChangeImage(1,image_index);
}
else
{
//--- !>E@0=8BL 8=45:A 2K1@0==>3> 87>1@065=8O
CElement::ChangeImage(0,image_index);
}
//--- 8AC5< :0@B8=:C
CElement::DrawImage();
}
//+------------------------------------------------------------------+