Consolidate Python ignore rules into root gitignore
@@ -0,0 +1,268 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| BmpButton.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndObj.mqh"
|
||||
#include <ChartObjects\ChartObjectsBmpControls.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CBmpButton |
|
||||
//| Usage: control that is displayed by |
|
||||
//| the CChartObjectBmpLabel object |
|
||||
//+------------------------------------------------------------------+
|
||||
class CBmpButton : public CWndObj
|
||||
{
|
||||
private:
|
||||
CChartObjectBmpLabel m_button; // chart object
|
||||
//--- parameters of the chart object
|
||||
int m_border; // border width
|
||||
string m_bmp_off_name; // name of BMP file for the "OFF" state (default state)
|
||||
string m_bmp_on_name; // name of BMP file for the "ON" state
|
||||
string m_bmp_passive_name;
|
||||
string m_bmp_active_name;
|
||||
|
||||
public:
|
||||
CBmpButton(void);
|
||||
~CBmpButton(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- parameters of the chart object
|
||||
int Border(void) const { return(m_border); }
|
||||
bool Border(const int value);
|
||||
bool BmpNames(const string off="",const string on="");
|
||||
string BmpOffName(void) const { return(m_bmp_off_name); }
|
||||
bool BmpOffName(const string name);
|
||||
string BmpOnName(void) const { return(m_bmp_on_name); }
|
||||
bool BmpOnName(const string name);
|
||||
string BmpPassiveName(void) const { return(m_bmp_passive_name); }
|
||||
bool BmpPassiveName(const string name);
|
||||
string BmpActiveName(void) const { return(m_bmp_active_name); }
|
||||
bool BmpActiveName(const string name);
|
||||
//--- state
|
||||
bool Pressed(void) const { return(m_button.State()); }
|
||||
bool Pressed(const bool pressed) { return(m_button.State(pressed)); }
|
||||
//--- properties
|
||||
bool Locking(void) const { return(IS_CAN_LOCK); }
|
||||
void Locking(const bool locking);
|
||||
|
||||
protected:
|
||||
//--- handlers of object settings
|
||||
virtual bool OnSetZOrder(void) { return(m_button.Z_Order(m_zorder)); }
|
||||
//--- internal event handlers
|
||||
virtual bool OnCreate(void);
|
||||
virtual bool OnShow(void);
|
||||
virtual bool OnHide(void);
|
||||
virtual bool OnMove(void);
|
||||
virtual bool OnChange(void);
|
||||
//--- íîâûå îáðàáîò÷èêè
|
||||
virtual bool OnActivate(void);
|
||||
virtual bool OnDeactivate(void);
|
||||
virtual bool OnMouseDown(void);
|
||||
virtual bool OnMouseUp(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CBmpButton::CBmpButton(void) : m_border(0),
|
||||
m_bmp_off_name(NULL),
|
||||
m_bmp_on_name(NULL),
|
||||
m_bmp_passive_name(NULL),
|
||||
m_bmp_active_name(NULL)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CBmpButton::~CBmpButton(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- call method of the parent class
|
||||
if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create the chart object
|
||||
if(!m_button.Create(chart,name,subwin,x1,y1))
|
||||
return(false);
|
||||
//--- call the settings handler
|
||||
return(OnChange());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set border width |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::Border(const int value)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_border=value;
|
||||
//--- set up the chart object
|
||||
return(m_button.Width(value));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set two images at once |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::BmpNames(const string off,const string on)
|
||||
{
|
||||
//--- save new values of parameters
|
||||
m_bmp_off_name=off;
|
||||
m_bmp_on_name =on;
|
||||
//--- set up the chart object
|
||||
if(!m_button.BmpFileOff(off))
|
||||
return(false);
|
||||
if(!m_button.BmpFileOn(on))
|
||||
return(false);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set image for the "OFF" state |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::BmpOffName(const string name)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_bmp_off_name=name;
|
||||
//--- set up the chart object
|
||||
if(!m_button.BmpFileOff(name))
|
||||
return(false);
|
||||
//--- set size by image dimensions
|
||||
Width(m_button.X_Size());
|
||||
Height(m_button.Y_Size());
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set image for the "ON" state |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::BmpOnName(const string name)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_bmp_on_name=name;
|
||||
//--- set up the chart object
|
||||
if(!m_button.BmpFileOn(name))
|
||||
return(false);
|
||||
//--- set size by image dimensions
|
||||
Width(m_button.X_Size());
|
||||
Height(m_button.Y_Size());
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set image for the "OFF" state (passive) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::BmpPassiveName(const string name)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_bmp_passive_name=name;
|
||||
//--- set up the chart object
|
||||
if(!IS_ACTIVE)
|
||||
return(BmpOffName(name));
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set image for the "OFF" state (active) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::BmpActiveName(const string name)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_bmp_active_name=name;
|
||||
//--- set up the chart object
|
||||
if(IS_ACTIVE)
|
||||
return(BmpOffName(name));
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Locking flag |
|
||||
//+------------------------------------------------------------------+
|
||||
void CBmpButton::Locking(const bool flag)
|
||||
{
|
||||
if(flag)
|
||||
PropFlagsSet(WND_PROP_FLAG_CAN_LOCK);
|
||||
else
|
||||
PropFlagsReset(WND_PROP_FLAG_CAN_LOCK);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create object on chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::OnCreate(void)
|
||||
{
|
||||
//--- create the chart object by previously set parameters
|
||||
return(m_button.Create(m_chart_id,m_name,m_subwin,m_rect.left,m_rect.top));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Display object on chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::OnShow(void)
|
||||
{
|
||||
return(m_button.Timeframes(OBJ_ALL_PERIODS));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Hide object from chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::OnHide(void)
|
||||
{
|
||||
return(m_button.Timeframes(OBJ_NO_PERIODS));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Absolute movement of the chart object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::OnMove(void)
|
||||
{
|
||||
//--- position the chart object
|
||||
return(m_button.X_Distance(m_rect.left) && m_button.Y_Distance(m_rect.top));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set up the chart object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::OnChange(void)
|
||||
{
|
||||
//--- set up the chart object
|
||||
return(m_button.Width(m_border) && m_button.BmpFileOff(m_bmp_off_name) && m_button.BmpFileOn(m_bmp_on_name));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of activating the group of controls |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::OnActivate(void)
|
||||
{
|
||||
if(m_bmp_active_name!=NULL)
|
||||
BmpOffName(m_bmp_active_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of deactivating the group of controls |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::OnDeactivate(void)
|
||||
{
|
||||
if(m_bmp_passive_name!=NULL)
|
||||
BmpOffName(m_bmp_passive_name);
|
||||
if(!IS_CAN_LOCK)
|
||||
Pressed(false);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on the left mouse button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::OnMouseDown(void)
|
||||
{
|
||||
if(!IS_CAN_LOCK)
|
||||
Pressed(!Pressed());
|
||||
//--- call of the method of the parent class
|
||||
return(CWnd::OnMouseDown());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on the left mouse button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CBmpButton::OnMouseUp(void)
|
||||
{
|
||||
//--- depress the button if it is not fixed
|
||||
if(m_button.State() && !IS_CAN_LOCK)
|
||||
m_button.State(false);
|
||||
//--- call of the method of the parent class
|
||||
return(CWnd::OnMouseUp());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,146 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Button.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndObj.mqh"
|
||||
#include <ChartObjects\ChartObjectsTxtControls.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CButton |
|
||||
//| Usage: control that is displayed by |
|
||||
//| the CChartObjectButton object |
|
||||
//+------------------------------------------------------------------+
|
||||
class CButton : public CWndObj
|
||||
{
|
||||
private:
|
||||
CChartObjectButton m_button; // chart object
|
||||
|
||||
public:
|
||||
CButton(void);
|
||||
~CButton(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- state
|
||||
bool Pressed(void) const { return(m_button.State()); }
|
||||
bool Pressed(const bool pressed) { return(m_button.State(pressed)); }
|
||||
//--- properties
|
||||
bool Locking(void) const { return(IS_CAN_LOCK); }
|
||||
void Locking(const bool flag);
|
||||
|
||||
protected:
|
||||
//--- handlers of object settings
|
||||
virtual bool OnSetText(void) { return(m_button.Description(m_text)); }
|
||||
virtual bool OnSetColor(void) { return(m_button.Color(m_color)); }
|
||||
virtual bool OnSetColorBackground(void) { return(m_button.BackColor(m_color_background)); }
|
||||
virtual bool OnSetColorBorder(void) { return(m_button.BorderColor(m_color_border)); }
|
||||
virtual bool OnSetFont(void) { return(m_button.Font(m_font)); }
|
||||
virtual bool OnSetFontSize(void) { return(m_button.FontSize(m_font_size)); }
|
||||
//--- internal event handlers
|
||||
virtual bool OnCreate(void);
|
||||
virtual bool OnShow(void);
|
||||
virtual bool OnHide(void);
|
||||
virtual bool OnMove(void);
|
||||
virtual bool OnResize(void);
|
||||
//--- íîâûå îáðàáîò÷èêè
|
||||
virtual bool OnMouseDown(void);
|
||||
virtual bool OnMouseUp(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CButton::CButton(void)
|
||||
{
|
||||
m_color =CONTROLS_BUTTON_COLOR;
|
||||
m_color_background=CONTROLS_BUTTON_COLOR_BG;
|
||||
m_color_border =CONTROLS_BUTTON_COLOR_BORDER;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CButton::~CButton(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CButton::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- call method of the parent class
|
||||
if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create the chart object
|
||||
if(!m_button.Create(chart,name,subwin,x1,y1,Width(),Height()))
|
||||
return(false);
|
||||
//--- call the settings handler
|
||||
return(OnChange());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Locking flag |
|
||||
//+------------------------------------------------------------------+
|
||||
void CButton::Locking(const bool flag)
|
||||
{
|
||||
if(flag)
|
||||
PropFlagsSet(WND_PROP_FLAG_CAN_LOCK);
|
||||
else
|
||||
PropFlagsReset(WND_PROP_FLAG_CAN_LOCK);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create object on chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CButton::OnCreate(void)
|
||||
{
|
||||
//--- create the chart object by previously set parameters
|
||||
return(m_button.Create(m_chart_id,m_name,m_subwin,m_rect.left,m_rect.top,m_rect.Width(),m_rect.Height()));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Display object on chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CButton::OnShow(void)
|
||||
{
|
||||
return(m_button.Timeframes(OBJ_ALL_PERIODS));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Hide object from chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CButton::OnHide(void)
|
||||
{
|
||||
return(m_button.Timeframes(OBJ_NO_PERIODS));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Absolute movement of the chart object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CButton::OnMove(void)
|
||||
{
|
||||
//--- position the chart object
|
||||
return(m_button.X_Distance(m_rect.left) && m_button.Y_Distance(m_rect.top));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resize the chart object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CButton::OnResize(void)
|
||||
{
|
||||
//--- resize the chart object
|
||||
return(m_button.X_Size(m_rect.Width()) && m_button.Y_Size(m_rect.Height()));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on the left mouse button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CButton::OnMouseDown(void)
|
||||
{
|
||||
if(!IS_CAN_LOCK)
|
||||
Pressed(!Pressed());
|
||||
//--- call of the method of the parent class
|
||||
return(CWnd::OnMouseDown());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on the left mouse button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CButton::OnMouseUp(void)
|
||||
{
|
||||
//--- depress the button if it is not fixed
|
||||
if(m_button.State() && !IS_CAN_LOCK)
|
||||
m_button.State(false);
|
||||
//--- call of the method of the parent class
|
||||
return(CWnd::OnMouseUp());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,183 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| CheckBox.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndContainer.mqh"
|
||||
#include "BmpButton.mqh"
|
||||
#include "Edit.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resources |
|
||||
//+------------------------------------------------------------------+
|
||||
#resource "res\\CheckBoxOn.bmp"
|
||||
#resource "res\\CheckBoxOff.bmp"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CCheckBox |
|
||||
//| Usage: class that implements the "CheckBox" control |
|
||||
//+------------------------------------------------------------------+
|
||||
class CCheckBox : public CWndContainer
|
||||
{
|
||||
private:
|
||||
//--- dependent controls
|
||||
CBmpButton m_button; // button object
|
||||
CEdit m_label; // label object
|
||||
//--- data
|
||||
int m_value; // value
|
||||
|
||||
public:
|
||||
CCheckBox(void);
|
||||
~CCheckBox(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- settings
|
||||
string Text(void) const { return(m_label.Text()); }
|
||||
bool Text(const string value) { return(m_label.Text(value)); }
|
||||
color Color(void) const { return(m_label.Color()); }
|
||||
bool Color(const color value) { return(m_label.Color(value)); }
|
||||
//--- state
|
||||
bool Checked(void) const { return(m_button.Pressed()); }
|
||||
bool Checked(const bool flag) { return(m_button.Pressed(flag)); }
|
||||
//--- data
|
||||
int Value(void) const { return(m_value); }
|
||||
void Value(const int value) { m_value=value; }
|
||||
//--- methods for working with files
|
||||
virtual bool Save(const int file_handle);
|
||||
virtual bool Load(const int file_handle);
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
virtual bool CreateButton(void);
|
||||
virtual bool CreateLabel(void);
|
||||
//--- handlers of the dependent controls events
|
||||
virtual bool OnClickButton(void);
|
||||
virtual bool OnClickLabel(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_BEGIN(CCheckBox)
|
||||
ON_EVENT(ON_CLICK,m_button,OnClickButton)
|
||||
ON_EVENT(ON_CLICK,m_label,OnClickLabel)
|
||||
EVENT_MAP_END(CWndContainer)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CCheckBox::CCheckBox(void) : m_value(0)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CCheckBox::~CCheckBox(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckBox::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- call method of the parent class
|
||||
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create dependent controls
|
||||
if(!CreateButton())
|
||||
return(false);
|
||||
if(!CreateLabel())
|
||||
return(false);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckBox::CreateButton(void)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=CONTROLS_CHECK_BUTTON_X_OFF;
|
||||
int y1=CONTROLS_CHECK_BUTTON_Y_OFF;
|
||||
int x2=x1+CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_BUTTON_SIZE-CONTROLS_BORDER_WIDTH;
|
||||
//--- create
|
||||
if(!m_button.Create(m_chart_id,m_name+"Button",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_button.BmpNames("::res\\CheckBoxOff.bmp","::res\\CheckBoxOn.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_button))
|
||||
return(false);
|
||||
m_button.Locking(true);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create label |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckBox::CreateLabel(void)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=CONTROLS_CHECK_LABEL_X_OFF;
|
||||
int y1=CONTROLS_CHECK_LABEL_Y_OFF;
|
||||
int x2=Width();
|
||||
int y2=Height();
|
||||
//--- create
|
||||
if(!m_label.Create(m_chart_id,m_name+"Label",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_label.Text(m_name))
|
||||
return(false);
|
||||
if(!Add(m_label))
|
||||
return(false);
|
||||
m_label.ReadOnly(true);
|
||||
m_label.ColorBackground(CONTROLS_CHECKGROUP_COLOR_BG);
|
||||
m_label.ColorBorder(CONTROLS_CHECKGROUP_COLOR_BG);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckBox::Save(const int file_handle)
|
||||
{
|
||||
//--- check
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//---
|
||||
FileWriteInteger(file_handle,Checked());
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckBox::Load(const int file_handle)
|
||||
{
|
||||
//--- check
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//---
|
||||
if(!FileIsEnding(file_handle))
|
||||
Checked(FileReadInteger(file_handle));
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckBox::OnClickButton(void)
|
||||
{
|
||||
//--- send the "changed state" event
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on label |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckBox::OnClickLabel(void)
|
||||
{
|
||||
//--- change button state
|
||||
m_button.Pressed(!m_button.Pressed());
|
||||
//--- return the result of the button click handler
|
||||
return(OnClickButton());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,377 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| CheckGroup.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndClient.mqh"
|
||||
#include "CheckBox.mqh"
|
||||
#include <Arrays\ArrayString.mqh>
|
||||
#include <Arrays\ArrayLong.mqh>
|
||||
#include <Arrays\ArrayInt.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CCheckGroup |
|
||||
//| Usage: view and edit group of flags |
|
||||
//+------------------------------------------------------------------+
|
||||
class CCheckGroup : public CWndClient
|
||||
{
|
||||
private:
|
||||
//--- dependent controls
|
||||
CCheckBox m_rows[]; // array of the row objects
|
||||
//--- set up
|
||||
int m_offset; // index of first visible row in array of rows
|
||||
int m_total_view; // number of visible rows
|
||||
int m_item_height; // height of visible row
|
||||
//--- data
|
||||
CArrayString m_strings; // array of rows
|
||||
CArrayLong m_values; // array of values
|
||||
CArrayInt m_states; // array of states
|
||||
long m_value; // current value
|
||||
int m_current; // index of current row in array of rows
|
||||
|
||||
public:
|
||||
CCheckGroup(void);
|
||||
~CCheckGroup(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
virtual void Destroy(const int reason=0);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- fill
|
||||
virtual bool AddItem(const string item,const long value=0);
|
||||
//--- data
|
||||
long Value(void) const;
|
||||
bool Value(const long value);
|
||||
int Check(const int idx) const;
|
||||
bool Check(const int idx,const int value);
|
||||
//--- state
|
||||
virtual bool Show(void);
|
||||
//--- methods for working with files
|
||||
virtual bool Save(const int file_handle);
|
||||
virtual bool Load(const int file_handle);
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
bool CreateButton(int index);
|
||||
//--- handlers of the dependent controls events
|
||||
virtual bool OnVScrollShow(void);
|
||||
virtual bool OnVScrollHide(void);
|
||||
virtual bool OnScrollLineDown(void);
|
||||
virtual bool OnScrollLineUp(void);
|
||||
virtual bool OnChangeItem(const int row_index);
|
||||
//--- redraw
|
||||
bool Redraw(void);
|
||||
bool RowState(const int index,const bool select);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_BEGIN(CCheckGroup)
|
||||
ON_INDEXED_EVENT(ON_CHANGE,m_rows,OnChangeItem)
|
||||
EVENT_MAP_END(CWndClient)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CCheckGroup::CCheckGroup(void) : m_offset(0),
|
||||
m_total_view(0),
|
||||
m_item_height(CONTROLS_LIST_ITEM_HEIGHT),
|
||||
m_current(CONTROLS_INVALID_INDEX),
|
||||
m_value(0)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CCheckGroup::~CCheckGroup(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- determine the number of visible rows
|
||||
m_total_view=(y2-y1)/m_item_height;
|
||||
//--- check the number of visible rows
|
||||
if(m_total_view<1)
|
||||
return(false);
|
||||
//--- call method of the parent class
|
||||
if(!CWndClient::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- set up
|
||||
if(!m_background.ColorBackground(CONTROLS_CHECKGROUP_COLOR_BG))
|
||||
return(false);
|
||||
if(!m_background.ColorBorder(CONTROLS_CHECKGROUP_COLOR_BORDER))
|
||||
return(false);
|
||||
//--- create dependent controls
|
||||
ArrayResize(m_rows,m_total_view);
|
||||
for(int i=0;i<m_total_view;i++)
|
||||
if(!CreateButton(i))
|
||||
return(false);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Delete group of controls |
|
||||
//+------------------------------------------------------------------+
|
||||
void CCheckGroup::Destroy(const int reason)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
CWndClient::Destroy(reason);
|
||||
//--- clear items
|
||||
m_strings.Clear();
|
||||
m_values.Clear();
|
||||
m_states.Clear();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create "row" |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::CreateButton(int index)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=CONTROLS_BORDER_WIDTH;
|
||||
int y1=CONTROLS_BORDER_WIDTH+m_item_height*index;
|
||||
int x2=Width()-CONTROLS_BORDER_WIDTH;
|
||||
int y2=y1+m_item_height;
|
||||
//--- create
|
||||
if(!m_rows[index].Create(m_chart_id,m_name+"Item"+IntegerToString(index),m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_rows[index].Text(""))
|
||||
return(false);
|
||||
if(!Add(m_rows[index]))
|
||||
return(false);
|
||||
m_rows[index].Hide();
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Add item (row) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::AddItem(const string item,const long value)
|
||||
{
|
||||
//--- add
|
||||
if(!m_strings.Add(item))
|
||||
return(false);
|
||||
if(!m_values.Add(value))
|
||||
return(false);
|
||||
if(!m_states.Add(0))
|
||||
return(false);
|
||||
//--- number of items
|
||||
int total=m_strings.Total();
|
||||
//--- exit if number of items does not exceed the size of visible area
|
||||
if(total<m_total_view+1)
|
||||
{
|
||||
if(IS_VISIBLE && total!=0)
|
||||
m_rows[total-1].Show();
|
||||
return(Redraw());
|
||||
}
|
||||
//--- if number of items exceeded the size of visible area
|
||||
if(total==m_total_view+1)
|
||||
{
|
||||
//--- enable vertical scrollbar
|
||||
if(!VScrolled(true))
|
||||
return(false);
|
||||
//--- and immediately make it invisible (if needed)
|
||||
if(!IS_VISIBLE)
|
||||
m_scroll_v.Visible(false);
|
||||
}
|
||||
//--- set up the scrollbar
|
||||
m_scroll_v.MaxPos(m_strings.Total()-m_total_view);
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
long CCheckGroup::Value(void) const
|
||||
{
|
||||
return(m_value);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::Value(const long value)
|
||||
{
|
||||
m_value=value;
|
||||
//---
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
int CCheckGroup::Check(const int idx) const
|
||||
{
|
||||
//--- check
|
||||
if(idx>=m_values.Total())
|
||||
return(0);
|
||||
//---
|
||||
return(m_states[idx]);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::Check(const int idx,const int value)
|
||||
{
|
||||
//--- check
|
||||
if(idx>=m_values.Total())
|
||||
return(false);
|
||||
//---
|
||||
bool res=(m_states.Update(idx,value) && Redraw());
|
||||
//--- change value
|
||||
if(res && idx<64)
|
||||
{
|
||||
if(m_rows[idx].Checked())
|
||||
Value(m_value|m_values.At(idx));
|
||||
else
|
||||
Value(m_value&(~m_values.At(idx)));
|
||||
}
|
||||
//---
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Makes the group visible |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::Show(void)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
if(!CWndClient::Show())
|
||||
return(false);
|
||||
//--- loop by rows
|
||||
int total=m_values.Total();
|
||||
for(int i=total;i<m_total_view;i++)
|
||||
m_rows[i].Hide();
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::Save(const int file_handle)
|
||||
{
|
||||
//--- check
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//---
|
||||
FileWriteLong(file_handle,Value());
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::Load(const int file_handle)
|
||||
{
|
||||
//--- check
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//---
|
||||
if(!FileIsEnding(file_handle))
|
||||
Value(FileReadLong(file_handle));
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Redraw |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::Redraw(void)
|
||||
{
|
||||
//--- loop by "rows"
|
||||
for(int i=0;i<m_total_view;i++)
|
||||
{
|
||||
//--- copy text
|
||||
if(!m_rows[i].Text(m_strings[i+m_offset]))
|
||||
return(false);
|
||||
//--- select
|
||||
if(!RowState(i,m_states[i+m_offset]!=0))
|
||||
return(false);
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Change state |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::RowState(const int index,const bool select)
|
||||
{
|
||||
//--- check index
|
||||
if(index<0 || index>=ArraySize(m_rows))
|
||||
return(true);
|
||||
//--- change state
|
||||
return(m_rows[index].Checked(select));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Show vertical scrollbar" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::OnVScrollShow(void)
|
||||
{
|
||||
//--- loop by "rows"
|
||||
for(int i=0;i<m_total_view;i++)
|
||||
{
|
||||
//--- resize "rows" according to shown vertical scrollbar
|
||||
m_rows[i].Width(Width()-(CONTROLS_SCROLL_SIZE+CONTROLS_BORDER_WIDTH));
|
||||
}
|
||||
//--- check visibility
|
||||
if(!IS_VISIBLE)
|
||||
{
|
||||
m_scroll_v.Visible(false);
|
||||
return(true);
|
||||
}
|
||||
//--- event is handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Hide vertical scrollbar" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::OnVScrollHide(void)
|
||||
{
|
||||
//--- check visibility
|
||||
if(!IS_VISIBLE)
|
||||
return(true);
|
||||
//--- loop by "rows"
|
||||
for(int i=0;i<m_total_view;i++)
|
||||
{
|
||||
//--- resize "rows" according to hidden vertical scroll bar
|
||||
m_rows[i].Width(Width()-CONTROLS_BORDER_WIDTH);
|
||||
}
|
||||
//--- event is handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Scroll up for one row" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::OnScrollLineUp(void)
|
||||
{
|
||||
//--- get new offset
|
||||
m_offset=m_scroll_v.CurrPos();
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Scroll down for one row" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::OnScrollLineDown(void)
|
||||
{
|
||||
//--- get new offset
|
||||
m_offset=m_scroll_v.CurrPos();
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of changing a "row" state |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CCheckGroup::OnChangeItem(const int row_index)
|
||||
{
|
||||
//--- change value
|
||||
m_states.Update(row_index+m_offset,m_rows[row_index].Checked());
|
||||
if(row_index+m_offset<64)
|
||||
{
|
||||
if(m_rows[row_index].Checked())
|
||||
Value(m_value|m_values.At(row_index+m_offset));
|
||||
else
|
||||
Value(m_value&(~m_values.At(row_index+m_offset)));
|
||||
}
|
||||
//--- send notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,324 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| ComboBox.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndContainer.mqh"
|
||||
#include "Edit.mqh"
|
||||
#include "BmpButton.mqh"
|
||||
#include "ListView.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resources |
|
||||
//+------------------------------------------------------------------+
|
||||
//--- Can not place the same file into resource twice
|
||||
#resource "res\\DropOn.bmp" // image file
|
||||
#resource "res\\DropOff.bmp" // image file
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CComboBox |
|
||||
//| Usage: drop-down list |
|
||||
//+------------------------------------------------------------------+
|
||||
class CComboBox : public CWndContainer
|
||||
{
|
||||
private:
|
||||
//--- dependent controls
|
||||
CEdit m_edit; // the entry field object
|
||||
CBmpButton m_drop; // the button object
|
||||
CListView m_list; // the drop-down list object
|
||||
//--- set up
|
||||
int m_item_height; // height of visible row
|
||||
int m_view_items; // number of visible rows in the drop-down list
|
||||
|
||||
public:
|
||||
CComboBox(void);
|
||||
~CComboBox(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- fill
|
||||
bool AddItem(const string item,const long value=0);
|
||||
//--- set up
|
||||
void ListViewItems(const int value) { m_view_items=value; }
|
||||
//--- data
|
||||
virtual bool ItemAdd(const string item,const long value=0) { return(m_list.ItemAdd(item,value)); }
|
||||
virtual bool ItemInsert(const int index,const string item,const long value=0) { return(m_list.ItemInsert(index,item,value)); }
|
||||
virtual bool ItemUpdate(const int index,const string item,const long value=0) { return(m_list.ItemUpdate(index,item,value)); }
|
||||
virtual bool ItemDelete(const int index) { return(m_list.ItemDelete(index)); }
|
||||
virtual bool ItemsClear(void) { return(m_list.ItemsClear()); }
|
||||
//--- data
|
||||
string Select(void) { return(m_edit.Text()); }
|
||||
bool Select(const int index);
|
||||
bool SelectByText(const string text);
|
||||
bool SelectByValue(const long value);
|
||||
//--- data (read only)
|
||||
long Value(void) { return(m_list.Value()); }
|
||||
//--- state
|
||||
virtual bool Show(void);
|
||||
//--- methods for working with files
|
||||
virtual bool Save(const int file_handle);
|
||||
virtual bool Load(const int file_handle);
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
virtual bool CreateEdit(void);
|
||||
virtual bool CreateButton(void);
|
||||
virtual bool CreateList(void);
|
||||
//--- handlers of the dependent controls events
|
||||
virtual bool OnClickEdit(void);
|
||||
virtual bool OnClickButton(void);
|
||||
virtual bool OnChangeList(void);
|
||||
//--- show drop-down list
|
||||
bool ListShow(void);
|
||||
bool ListHide(void);
|
||||
void CheckListHide(const int id,int x,int y);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_BEGIN(CComboBox)
|
||||
ON_EVENT(ON_CLICK,m_edit,OnClickEdit)
|
||||
ON_EVENT(ON_CLICK,m_drop,OnClickButton)
|
||||
ON_EVENT(ON_CHANGE,m_list,OnChangeList)
|
||||
CheckListHide(id,(int)lparam,(int)dparam);
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_END(CWndContainer)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CComboBox::CComboBox(void) : m_item_height(CONTROLS_COMBO_ITEM_HEIGHT),
|
||||
m_view_items(CONTROLS_COMBO_ITEMS_VIEW)
|
||||
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CComboBox::~CComboBox(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- check height
|
||||
if(y2-y1<CONTROLS_COMBO_MIN_HEIGHT)
|
||||
return(false);
|
||||
//--- call method of the parent class
|
||||
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create dependent controls
|
||||
if(!CreateEdit())
|
||||
return(false);
|
||||
if(!CreateButton())
|
||||
return(false);
|
||||
if(!CreateList())
|
||||
return(false);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create main entry field |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::CreateEdit(void)
|
||||
{
|
||||
//--- create
|
||||
if(!m_edit.Create(m_chart_id,m_name+"Edit",m_subwin,0,0,Width(),Height()))
|
||||
return(false);
|
||||
if(!m_edit.Text(""))
|
||||
return(false);
|
||||
if(!m_edit.ReadOnly(true))
|
||||
return(false);
|
||||
if(!Add(m_edit))
|
||||
return(false);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::CreateButton(void)
|
||||
{
|
||||
//--- right align button (try to make equal offsets from top and bottom)
|
||||
int x1=Width()-(CONTROLS_BUTTON_SIZE+CONTROLS_COMBO_BUTTON_X_OFF);
|
||||
int y1=(Height()-CONTROLS_BUTTON_SIZE)/2;
|
||||
int x2=x1+CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_BUTTON_SIZE;
|
||||
//--- create
|
||||
if(!m_drop.Create(m_chart_id,m_name+"Drop",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_drop.BmpNames("::res\\DropOff.bmp","::res\\DropOn.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_drop))
|
||||
return(false);
|
||||
m_drop.Locking(true);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create drop-down list |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::CreateList(void)
|
||||
{
|
||||
//--- create
|
||||
if(m_list.TotalView(m_view_items))
|
||||
{
|
||||
if(!m_list.Create(m_chart_id,m_name+"List",m_subwin,0,Height(),Width(),0))
|
||||
return(false);
|
||||
if(!Add(m_list))
|
||||
return(false);
|
||||
m_list.Hide();
|
||||
}
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Add item (row) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::AddItem(const string item,const long value)
|
||||
{
|
||||
//--- add item to list
|
||||
return(m_list.AddItem(item,value));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Select item |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::Select(const int index)
|
||||
{
|
||||
if(!m_list.Select(index))
|
||||
return(false);
|
||||
//--- call the handler
|
||||
return(OnChangeList());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Select item (by text) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::SelectByText(const string text)
|
||||
{
|
||||
if(!m_list.SelectByText(text))
|
||||
return(false);
|
||||
//--- call the handler
|
||||
return(OnChangeList());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Select item (by value) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::SelectByValue(const long value)
|
||||
{
|
||||
if(!m_list.SelectByValue(value))
|
||||
return(false);
|
||||
//--- call the handler
|
||||
return(OnChangeList());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Makes the control visible |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::Show(void)
|
||||
{
|
||||
m_edit.Show();
|
||||
m_drop.Show();
|
||||
m_list.Hide();
|
||||
//--- call of the method of the parent class
|
||||
return(CWnd::Show());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::Save(const int file_handle)
|
||||
{
|
||||
//--- check
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//---
|
||||
FileWriteLong(file_handle,Value());
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::Load(const int file_handle)
|
||||
{
|
||||
//--- check
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//---
|
||||
if(!FileIsEnding(file_handle))
|
||||
SelectByValue(FileReadLong(file_handle));
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on main entry field |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::OnClickEdit(void)
|
||||
{
|
||||
//--- change button state
|
||||
if(!m_drop.Pressed(!m_drop.Pressed()))
|
||||
return(false);
|
||||
//--- call the click on button handler
|
||||
return(OnClickButton());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::OnClickButton(void)
|
||||
{
|
||||
//--- show or hide the drop-down list depending on the button state
|
||||
return((m_drop.Pressed()) ? ListShow() : ListHide());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on drop-down list |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::OnChangeList(void)
|
||||
{
|
||||
string text=m_list.Select();
|
||||
//--- hide the list, depress the button
|
||||
ListHide();
|
||||
m_drop.Pressed(false);
|
||||
//--- set text in the main entry field
|
||||
m_edit.Text(text);
|
||||
//--- send notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Show the drop-down list |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::ListShow(void)
|
||||
{
|
||||
BringToTop();
|
||||
//--- show the list
|
||||
return(m_list.Show());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Hide drop-down list |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CComboBox::ListHide(void)
|
||||
{
|
||||
//--- hide the list
|
||||
return(m_list.Hide());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Hide the drop-down element if necessary |
|
||||
//+------------------------------------------------------------------+
|
||||
void CComboBox::CheckListHide(const int id,int x,int y)
|
||||
{
|
||||
//--- check event ID
|
||||
if(id!=CHARTEVENT_CLICK)
|
||||
return;
|
||||
//--- check visibility of the drop-down element
|
||||
if(!m_list.IsVisible())
|
||||
return;
|
||||
//--- check mouse cursor's position
|
||||
y-=(int)ChartGetInteger(m_chart_id,CHART_WINDOW_YDISTANCE,m_subwin);
|
||||
if(!m_edit.Contains(x,y) && !m_list.Contains(x,y))
|
||||
{
|
||||
m_drop.Pressed(false);
|
||||
m_list.Hide();
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,413 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| DateDropList.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndContainer.mqh"
|
||||
#include "BmpButton.mqh"
|
||||
#include "Picture.mqh"
|
||||
#include <Canvas\Canvas.mqh>
|
||||
#include <Tools\DateTime.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Enumerations |
|
||||
//+------------------------------------------------------------------+
|
||||
//--- date modes
|
||||
enum ENUM_DATE_MODES
|
||||
{
|
||||
DATE_MODE_MON, // month mode
|
||||
DATE_MODE_YEAR // year mode
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resources |
|
||||
//+------------------------------------------------------------------+
|
||||
//--- Can not place the same file into resource twice
|
||||
#resource "res\\LeftTransp.bmp"
|
||||
#resource "res\\RightTransp.bmp"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CDateDropList |
|
||||
//| Usage: drop-down list |
|
||||
//+------------------------------------------------------------------+
|
||||
class CDateDropList : public CWndContainer
|
||||
{
|
||||
private:
|
||||
//--- dependent controls
|
||||
CBmpButton m_dec; // the button object
|
||||
CBmpButton m_inc; // the button object
|
||||
CPicture m_list; // the drop-down list object
|
||||
CCanvas m_canvas; // and its canvas
|
||||
//--- data
|
||||
CDateTime m_value; // current value
|
||||
//--- variable
|
||||
ENUM_DATE_MODES m_mode; // operation mode
|
||||
CRect m_click_rect[32]; // array of click sensibility areas on canvas
|
||||
|
||||
public:
|
||||
CDateDropList(void);
|
||||
~CDateDropList(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- data
|
||||
datetime Value(void) { return(StructToTime(m_value)); }
|
||||
void Value(datetime value) { m_value.Date(value); }
|
||||
void Value(MqlDateTime& value) { (MqlDateTime&)m_value=value; }
|
||||
//--- state
|
||||
virtual bool Show(void);
|
||||
|
||||
protected:
|
||||
//--- internal event handlers
|
||||
virtual bool OnClick(void);
|
||||
//--- create dependent controls
|
||||
virtual bool CreateButtons(void);
|
||||
virtual bool CreateList(void);
|
||||
//--- draw
|
||||
void DrawCanvas(void);
|
||||
void DrawClickRect(const int idx,int x,int y,string text,const uint clr,uint alignment=0);
|
||||
//--- handlers of the dependent controls events
|
||||
virtual bool OnClickDec(void);
|
||||
virtual bool OnClickInc(void);
|
||||
virtual bool OnClickList(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_BEGIN(CDateDropList)
|
||||
ON_EVENT(ON_CLICK,m_dec,OnClickDec)
|
||||
ON_EVENT(ON_CLICK,m_inc,OnClickInc)
|
||||
ON_EVENT(ON_CLICK,m_list,OnClickList)
|
||||
EVENT_MAP_END(CWndContainer)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CDateDropList::CDateDropList(void) : m_mode(DATE_MODE_MON)
|
||||
{
|
||||
ZeroMemory(m_value);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CDateDropList::~CDateDropList(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDateDropList::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- need to find dimensions depending on font size
|
||||
//--- width 7 columns + 2 offsets
|
||||
int w=7*(2*CONTROLS_FONT_SIZE)+2*CONTROLS_FONT_SIZE;
|
||||
//--- header height + 7 rows
|
||||
int h=(CONTROLS_BUTTON_SIZE+4*CONTROLS_BORDER_WIDTH)+7*(2*CONTROLS_FONT_SIZE);
|
||||
//--- call method of the parent class
|
||||
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x1+w,y1+h))
|
||||
return(false);
|
||||
//--- create dependent controls
|
||||
if(!CreateList())
|
||||
return(false);
|
||||
if(!CreateButtons())
|
||||
return(false);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create drop-down list |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDateDropList::CreateList(void)
|
||||
{
|
||||
//--- create object
|
||||
if(!m_list.Create(m_chart_id,m_name+"List",m_subwin,0,0,Width(),Height()))
|
||||
return(false);
|
||||
if(!Add(m_list))
|
||||
return(false);
|
||||
//--- create canvas
|
||||
if(!m_canvas.Create(m_name,Width(),Height()))
|
||||
return(false);
|
||||
m_canvas.FontSet(CONTROLS_FONT_NAME,CONTROLS_FONT_SIZE*(-10));
|
||||
m_list.BmpName(m_canvas.ResourceName());
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create buttons |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDateDropList::CreateButtons(void)
|
||||
{
|
||||
//--- right align button (try to make equal offsets from top and bottom)
|
||||
int x1=2*CONTROLS_BORDER_WIDTH;
|
||||
int y1=2*CONTROLS_BORDER_WIDTH;
|
||||
int x2=x1+CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_BUTTON_SIZE;
|
||||
//--- create "Dec" button
|
||||
if(!m_dec.Create(m_chart_id,m_name+"Dec",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_dec.BmpNames("::res\\LeftTransp.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_dec))
|
||||
return(false);
|
||||
//---
|
||||
x2=Width()-2*CONTROLS_BORDER_WIDTH;
|
||||
x1=x2-CONTROLS_BUTTON_SIZE;
|
||||
//--- create "Inc" button
|
||||
if(!m_inc.Create(m_chart_id,m_name+"Inc",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_inc.BmpNames("::res\\RightTransp.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_inc))
|
||||
return(false);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Makes the control visible |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDateDropList::Show(void)
|
||||
{
|
||||
//--- draw canvas
|
||||
DrawCanvas();
|
||||
//--- call method of the parent class
|
||||
return(CWndContainer::Show());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDateDropList::OnClickDec(void)
|
||||
{
|
||||
switch(m_mode)
|
||||
{
|
||||
//--- within the month
|
||||
case DATE_MODE_MON:
|
||||
m_value.MonDec();
|
||||
break;
|
||||
//--- within the year
|
||||
case DATE_MODE_YEAR:
|
||||
m_value.YearDec();
|
||||
break;
|
||||
}
|
||||
DrawCanvas();
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDateDropList::OnClickInc(void)
|
||||
{
|
||||
switch(m_mode)
|
||||
{
|
||||
//--- within the month
|
||||
case DATE_MODE_MON:
|
||||
m_value.MonInc();
|
||||
break;
|
||||
//--- within the year
|
||||
case DATE_MODE_YEAR:
|
||||
m_value.YearInc();
|
||||
break;
|
||||
}
|
||||
DrawCanvas();
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on picture |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDateDropList::OnClickList(void)
|
||||
{
|
||||
m_mouse_x=m_list.MouseX();
|
||||
m_mouse_y=m_list.MouseY();
|
||||
//---
|
||||
OnClick();
|
||||
//---
|
||||
m_mouse_x=0;
|
||||
m_mouse_y=0;
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "click" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDateDropList::OnClick(void)
|
||||
{
|
||||
for(int i=0;i<32;i++)
|
||||
{
|
||||
if(m_click_rect[i].Contains(m_mouse_x,m_mouse_y))
|
||||
{
|
||||
if(i==0)
|
||||
{
|
||||
//--- clicked on the header
|
||||
switch(m_mode)
|
||||
{
|
||||
//--- within the month
|
||||
case DATE_MODE_MON:
|
||||
//--- switch to the "within the year" mode
|
||||
m_mode=DATE_MODE_YEAR;
|
||||
DrawCanvas();
|
||||
break;
|
||||
//--- within the year
|
||||
case DATE_MODE_YEAR:
|
||||
//--- do nothing for now
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- selected
|
||||
switch(m_mode)
|
||||
{
|
||||
//--- within the month
|
||||
case DATE_MODE_MON:
|
||||
m_value.Day(i);
|
||||
Hide();
|
||||
//--- send notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
|
||||
break;
|
||||
//--- within the year
|
||||
case DATE_MODE_YEAR:
|
||||
m_value.Mon(i);
|
||||
m_mode=DATE_MODE_MON;
|
||||
DrawCanvas();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Draw canvas |
|
||||
//+------------------------------------------------------------------+
|
||||
void CDateDropList::DrawCanvas(void)
|
||||
{
|
||||
int x,y;
|
||||
int dx,dy;
|
||||
string text;
|
||||
uint text_al=TA_CENTER|TA_VCENTER;
|
||||
CDateTime tmp_date;
|
||||
int rows,cols;
|
||||
int idx;
|
||||
//--- zero out array of areas
|
||||
for(int i=0;i<32;i++)
|
||||
ZeroMemory(m_click_rect[i]);
|
||||
//---
|
||||
m_canvas.Erase(COLOR2RGB(CONTROLS_EDIT_COLOR_BG));
|
||||
m_canvas.Rectangle(0,0,Width()-1,Height()-1,COLOR2RGB(CONTROLS_EDIT_COLOR_BORDER));
|
||||
x=Width()/2;
|
||||
y=CONTROLS_BUTTON_SIZE/2+2*CONTROLS_BORDER_WIDTH;
|
||||
switch(m_mode)
|
||||
{
|
||||
//--- within the month
|
||||
case DATE_MODE_MON:
|
||||
text=m_value.MonthName()+" "+IntegerToString(m_value.year);
|
||||
DrawClickRect(0,x,y,text,COLOR2RGB(CONTROLS_EDIT_COLOR),text_al);
|
||||
rows=6;
|
||||
cols=7;
|
||||
x=dx=Width()/(cols+1);
|
||||
y+=y;
|
||||
dy=(Height()-y-2*CONTROLS_BORDER_WIDTH)/(rows+1);
|
||||
y+=dy/2;
|
||||
for(int i=0;i<cols;i++,x+=dx)
|
||||
m_canvas.TextOut(x,y,m_value.ShortDayName(i),COLOR2RGB(CONTROLS_EDIT_COLOR),text_al);
|
||||
//--- backup data
|
||||
tmp_date=m_value;
|
||||
//--- find the beginning of the first displayed week
|
||||
tmp_date.DayDec(tmp_date.day_of_week);
|
||||
while(tmp_date.mon==m_value.mon && tmp_date.day!=1)
|
||||
tmp_date.DayDec(cols);
|
||||
//--- draw
|
||||
idx=1;
|
||||
y+=dy;
|
||||
for(int i=0;i<rows;i++,y+=dy)
|
||||
{
|
||||
x=dx;
|
||||
for(int j=0;j<cols;j++,x+=dx)
|
||||
{
|
||||
text=IntegerToString(tmp_date.day);
|
||||
if(tmp_date.mon==m_value.mon)
|
||||
{
|
||||
if(tmp_date.day==m_value.day)
|
||||
m_canvas.FillRectangle(x-dx/2,y-dy/2,x+dx/2,y+dy/2,COLOR2RGB(CONTROLS_COLOR_BG_SEL));
|
||||
DrawClickRect(idx++,x,y,text,COLOR2RGB(CONTROLS_EDIT_COLOR),text_al);
|
||||
}
|
||||
else
|
||||
m_canvas.TextOut(x,y,text,COLOR2RGB(CONTROLS_BUTTON_COLOR_BORDER),text_al);
|
||||
tmp_date.DayInc();
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--- within the year
|
||||
case DATE_MODE_YEAR:
|
||||
text=IntegerToString(m_value.year);
|
||||
DrawClickRect(0,x,y,text,COLOR2RGB(CONTROLS_EDIT_COLOR),text_al);
|
||||
rows=3;
|
||||
cols=4;
|
||||
x=dx=Width()/(cols+1);
|
||||
y+=y;
|
||||
dy=(Height()-y)/rows;
|
||||
y+=dy/2;
|
||||
for(int i=0;i<rows*cols;i++)
|
||||
{
|
||||
if(i+1==m_value.mon)
|
||||
m_canvas.FillRectangle(x-dx/2,y-dy/4,x+dx/2,y+dy/4,COLOR2RGB(CONTROLS_COLOR_BG_SEL));
|
||||
DrawClickRect(i+1,x,y,m_value.ShortMonthName(i+1),COLOR2RGB(CONTROLS_EDIT_COLOR),text_al);
|
||||
if(i%cols==cols-1)
|
||||
{
|
||||
x=dx;
|
||||
y+=dy;
|
||||
}
|
||||
else
|
||||
x+=dx;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_canvas.Update();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void CDateDropList::DrawClickRect(const int idx,int x,int y,string text,const uint clr,uint alignment)
|
||||
{
|
||||
int text_w,text_h;
|
||||
//--- display the text
|
||||
m_canvas.TextOut(x,y,text,clr,alignment);
|
||||
//--- determine area occupied by text
|
||||
m_canvas.TextSize(text,text_w,text_h);
|
||||
//--- convert relative coordinated to absolute ones
|
||||
x+=Left();
|
||||
y+=Top();
|
||||
//--- check flags of horizontal alignment
|
||||
switch(alignment&(TA_LEFT|TA_CENTER|TA_RIGHT))
|
||||
{
|
||||
case TA_LEFT:
|
||||
m_click_rect[idx].left=x;
|
||||
break;
|
||||
case TA_CENTER:
|
||||
m_click_rect[idx].left=x-text_w/2;
|
||||
break;
|
||||
case TA_RIGHT:
|
||||
m_click_rect[idx].left=x-text_w;
|
||||
break;
|
||||
}
|
||||
m_click_rect[idx].Width(text_w);
|
||||
//--- check flags of vertical alignment
|
||||
switch(alignment&(TA_TOP|TA_VCENTER|TA_BOTTOM))
|
||||
{
|
||||
case TA_TOP:
|
||||
m_click_rect[idx].top=y;
|
||||
break;
|
||||
case TA_VCENTER:
|
||||
m_click_rect[idx].top=y-text_h/2;
|
||||
break;
|
||||
case TA_BOTTOM:
|
||||
m_click_rect[idx].top=y-text_h;
|
||||
break;
|
||||
}
|
||||
m_click_rect[idx].Height(text_h);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,264 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| DatePicker.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndContainer.mqh"
|
||||
#include "Edit.mqh"
|
||||
#include "BmpButton.mqh"
|
||||
#include "DateDropList.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resources |
|
||||
//+------------------------------------------------------------------+
|
||||
//--- Can not place the same file into resource twice
|
||||
#resource "res\\DateDropOn.bmp" // image file
|
||||
#resource "res\\DateDropOff.bmp" // image file
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CDatePicker |
|
||||
//| Usage: date picker |
|
||||
//+------------------------------------------------------------------+
|
||||
class CDatePicker : public CWndContainer
|
||||
{
|
||||
private:
|
||||
//--- dependent controls
|
||||
CEdit m_edit; // the entry field object
|
||||
CBmpButton m_drop; // the button object
|
||||
CDateDropList m_list; // the drop-down list object
|
||||
//--- data
|
||||
datetime m_value; // current value
|
||||
|
||||
public:
|
||||
CDatePicker(void);
|
||||
~CDatePicker(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- data
|
||||
datetime Value(void) const { return(m_value); }
|
||||
void Value(datetime value) { m_edit.Text(TimeToString(m_value=value,TIME_DATE)); }
|
||||
//--- state
|
||||
virtual bool Show(void);
|
||||
//--- methods for working with files
|
||||
virtual bool Save(const int file_handle);
|
||||
virtual bool Load(const int file_handle);
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
virtual bool CreateEdit(void);
|
||||
virtual bool CreateButton(void);
|
||||
virtual bool CreateList(void);
|
||||
//--- handlers of the dependent controls events
|
||||
virtual bool OnClickEdit(void);
|
||||
virtual bool OnClickButton(void);
|
||||
virtual bool OnChangeList(void);
|
||||
//--- show drop-down list
|
||||
bool ListShow(void);
|
||||
bool ListHide(void);
|
||||
void CheckListHide(const int id,int x,int y);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_BEGIN(CDatePicker)
|
||||
ON_EVENT(ON_CLICK,m_edit,OnClickEdit)
|
||||
ON_EVENT(ON_CLICK,m_drop,OnClickButton)
|
||||
ON_EVENT(ON_CHANGE,m_list,OnChangeList)
|
||||
CheckListHide(id,(int)lparam,(int)dparam);
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_END(CWndContainer)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CDatePicker::CDatePicker(void) : m_value(0)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CDatePicker::~CDatePicker(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDatePicker::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- call method of the parent class
|
||||
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create dependent controls
|
||||
if(!CreateEdit())
|
||||
return(false);
|
||||
if(!CreateButton())
|
||||
return(false);
|
||||
if(!CreateList())
|
||||
return(false);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create main entry field |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDatePicker::CreateEdit(void)
|
||||
{
|
||||
//--- create
|
||||
if(!m_edit.Create(m_chart_id,m_name+"Edit",m_subwin,0,0,Width(),Height()))
|
||||
return(false);
|
||||
if(!m_edit.Text(""))
|
||||
return(false);
|
||||
if(!m_edit.ReadOnly(true))
|
||||
return(false);
|
||||
if(!Add(m_edit))
|
||||
return(false);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDatePicker::CreateButton(void)
|
||||
{
|
||||
//--- right align button (try to make equal offsets from top and bottom)
|
||||
int x1=Width()-(2*CONTROLS_BUTTON_SIZE+CONTROLS_COMBO_BUTTON_X_OFF);
|
||||
int y1=(Height()-CONTROLS_BUTTON_SIZE)/2;
|
||||
int x2=x1+2*CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_BUTTON_SIZE;
|
||||
//--- create
|
||||
if(!m_drop.Create(m_chart_id,m_name+"Drop",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_drop.BmpNames("::res\\DateDropOff.bmp","::res\\DateDropOn.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_drop))
|
||||
return(false);
|
||||
m_drop.Locking(true);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create drop-down list |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDatePicker::CreateList(void)
|
||||
{
|
||||
//--- create
|
||||
if(!m_list.Create(m_chart_id,m_name+"List",m_subwin,0,Height()-1,Width(),0))
|
||||
return(false);
|
||||
if(!Add(m_list))
|
||||
return(false);
|
||||
m_list.Hide();
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Makes the control visible |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDatePicker::Show(void)
|
||||
{
|
||||
m_edit.Show();
|
||||
m_drop.Show();
|
||||
m_list.Hide();
|
||||
//--- call method of the parent class
|
||||
return(CWnd::Show());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| save |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDatePicker::Save(const int file_handle)
|
||||
{
|
||||
//--- check
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//--- write
|
||||
FileWriteLong(file_handle,Value());
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| load |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDatePicker::Load(const int file_handle)
|
||||
{
|
||||
//--- check
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//--- load
|
||||
if(!FileIsEnding(file_handle))
|
||||
Value(FileReadLong(file_handle));
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on main entry field |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDatePicker::OnClickEdit(void)
|
||||
{
|
||||
//--- change button state
|
||||
if(!m_drop.Pressed(!m_drop.Pressed()))
|
||||
return(false);
|
||||
//--- call the click on button handler
|
||||
return(OnClickButton());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDatePicker::OnClickButton(void)
|
||||
{
|
||||
//--- show or hide the drop-down list depending on the button state
|
||||
return((m_drop.Pressed()) ? ListShow():ListHide());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of change on drop-down list |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDatePicker::OnChangeList(void)
|
||||
{
|
||||
string text=TimeToString(m_value=m_list.Value(),TIME_DATE);
|
||||
//--- hide the list, depress the button
|
||||
ListHide();
|
||||
m_drop.Pressed(false);
|
||||
//--- set text in the main entry field
|
||||
m_edit.Text(text);
|
||||
//--- send notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Show the drop-down list |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDatePicker::ListShow(void)
|
||||
{
|
||||
//--- set value
|
||||
m_list.Value(m_value);
|
||||
//--- show the list
|
||||
return(m_list.Show());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Hide drop-down list |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDatePicker::ListHide(void)
|
||||
{
|
||||
//--- hide the list
|
||||
return(m_list.Hide());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Hide the drop-down element if necessary |
|
||||
//+------------------------------------------------------------------+
|
||||
void CDatePicker::CheckListHide(const int id,int x,int y)
|
||||
{
|
||||
//--- check event ID
|
||||
if(id!=CHARTEVENT_CLICK)
|
||||
return;
|
||||
//--- check visibility of the drop-down element
|
||||
if(!m_list.IsVisible())
|
||||
return;
|
||||
//--- check mouse cursor's position
|
||||
y-=(int)ChartGetInteger(m_chart_id,CHART_WINDOW_YDISTANCE,m_subwin);
|
||||
if(!m_edit.Contains(x,y) && !m_list.Contains(x,y))
|
||||
{
|
||||
m_drop.Pressed(false);
|
||||
m_list.Hide();
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,190 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Defines.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
//| Enumerations |
|
||||
//+------------------------------------------------------------------+
|
||||
//--- properties flags
|
||||
enum ENUM_WND_PROP_FLAGS
|
||||
{
|
||||
WND_PROP_FLAG_CAN_DBL_CLICK = 1, // can be double clicked by mouse
|
||||
WND_PROP_FLAG_CAN_DRAG = 2, // can be dragged by mouse
|
||||
WND_PROP_FLAG_CLICKS_BY_PRESS= 4, // generates the "click" event series on pressing left mouse button
|
||||
WND_PROP_FLAG_CAN_LOCK = 8, // control with fixed state (usually it is a button)
|
||||
WND_PROP_FLAG_READ_ONLY =16 // read only (usually it is a edit)
|
||||
};
|
||||
//--- state flags
|
||||
enum ENUM_WND_STATE_FLAGS
|
||||
{
|
||||
WND_STATE_FLAG_ENABLE = 1, // "object is enabled" flag
|
||||
WND_STATE_FLAG_VISIBLE = 2, // "object is visible" flag
|
||||
WND_STATE_FLAG_ACTIVE = 4, // "object is active" flag
|
||||
};
|
||||
//--- mouse flags
|
||||
enum ENUM_MOUSE_FLAGS
|
||||
{
|
||||
MOUSE_INVALID_FLAGS =-1, // no buttons state
|
||||
MOUSE_EMPTY = 0, // buttons are not pressed
|
||||
MOUSE_LEFT = 1, // left button pressed
|
||||
MOUSE_RIGHT = 2 // right button pressed
|
||||
};
|
||||
//--- alignment flags
|
||||
enum ENUM_WND_ALIGN_FLAGS
|
||||
{
|
||||
WND_ALIGN_NONE = 0, // no alignment
|
||||
WND_ALIGN_LEFT = 1, // align by left border
|
||||
WND_ALIGN_TOP = 2, // align by top border
|
||||
WND_ALIGN_RIGHT = 4, // align by right border
|
||||
WND_ALIGN_BOTTOM = 8, // align by bottom border
|
||||
WND_ALIGN_WIDTH = WND_ALIGN_LEFT|WND_ALIGN_RIGHT, // justify
|
||||
WND_ALIGN_HEIGHT = WND_ALIGN_TOP|WND_ALIGN_BOTTOM, // align by top and bottom border
|
||||
WND_ALIGN_CLIENT = WND_ALIGN_WIDTH|WND_ALIGN_HEIGHT // align by all sides
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Drawing styles and colors |
|
||||
//+------------------------------------------------------------------+
|
||||
//--- common
|
||||
#define CONTROLS_FONT_NAME "Trebuchet MS"
|
||||
#define CONTROLS_FONT_SIZE (10)
|
||||
//--- Text
|
||||
#define CONTROLS_COLOR_TEXT C'0x3B,0x29,0x28'
|
||||
#define CONTROLS_COLOR_TEXT_SEL clrWhite
|
||||
#define CONTROLS_COLOR_BG clrWhite
|
||||
#define CONTROLS_COLOR_BG_SEL C'0x33,0x99,0xFF'
|
||||
//--- Button
|
||||
#define CONTROLS_BUTTON_COLOR C'0x3B,0x29,0x28'
|
||||
#define CONTROLS_BUTTON_COLOR_BG C'0xDD,0xE2,0xEB'
|
||||
#define CONTROLS_BUTTON_COLOR_BORDER C'0xB2,0xC3,0xCF'
|
||||
//--- Label
|
||||
#define CONTROLS_LABEL_COLOR C'0x3B,0x29,0x28'
|
||||
//--- Edit
|
||||
#define CONTROLS_EDIT_COLOR C'0x3B,0x29,0x28'
|
||||
#define CONTROLS_EDIT_COLOR_BG clrWhite
|
||||
#define CONTROLS_EDIT_COLOR_BORDER C'0xB2,0xC3,0xCF'
|
||||
//--- Scrolls
|
||||
#define CONTROLS_SCROLL_COLOR_BG C'0xEC,0xEC,0xEC'
|
||||
#define CONTROLS_SCROLL_COLOR_BORDER C'0xD3,0xD3,0xD3'
|
||||
//--- Client
|
||||
#define CONTROLS_CLIENT_COLOR_BG C'0xDE,0xDE,0xDE'
|
||||
#define CONTROLS_CLIENT_COLOR_BORDER C'0x2C,0x2C,0x2C'
|
||||
//--- ListView
|
||||
#define CONTROLS_LISTITEM_COLOR_TEXT C'0x3B,0x29,0x28'
|
||||
#define CONTROLS_LISTITEM_COLOR_TEXT_SEL clrWhite
|
||||
#define CONTROLS_LISTITEM_COLOR_BG clrWhite
|
||||
#define CONTROLS_LISTITEM_COLOR_BG_SEL C'0x33,0x99,0xFF'
|
||||
#define CONTROLS_LIST_COLOR_BG clrWhite
|
||||
#define CONTROLS_LIST_COLOR_BORDER C'0xB2,0xC3,0xCF'
|
||||
//--- CheckGroup
|
||||
#define CONTROLS_CHECKGROUP_COLOR_BG C'0xF7,0xF7,0xF7'
|
||||
#define CONTROLS_CHECKGROUP_COLOR_BORDER C'0xB2,0xC3,0xCF'
|
||||
//--- RadioGroup
|
||||
#define CONTROLS_RADIOGROUP_COLOR_BG C'0xF7,0xF7,0xF7'
|
||||
#define CONTROLS_RADIOGROUP_COLOR_BORDER C'0xB2,0xC3,0xCF'
|
||||
//--- Dialog
|
||||
#define CONTROLS_DIALOG_COLOR_BORDER_LIGHT clrWhite
|
||||
#define CONTROLS_DIALOG_COLOR_BORDER_DARK C'0xB6,0xB6,0xB6'
|
||||
#define CONTROLS_DIALOG_COLOR_BG C'0xF0,0xF0,0xF0'
|
||||
#define CONTROLS_DIALOG_COLOR_CAPTION_TEXT C'0x28,0x29,0x3B'
|
||||
#define CONTROLS_DIALOG_COLOR_CLIENT_BG C'0xF7,0xF7,0xF7'
|
||||
#define CONTROLS_DIALOG_COLOR_CLIENT_BORDER C'0xC8,0xC8,0xC8'
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constants for the controls |
|
||||
//+------------------------------------------------------------------+
|
||||
//--- common
|
||||
#define CONTROLS_INVALID_ID (-1) // invalid ID
|
||||
#define CONTROLS_INVALID_INDEX (-1) // invalid index of array
|
||||
#define CONTROLS_SELF_MESSAGE (-1) // message to oneself
|
||||
#define CONTROLS_MAXIMUM_ID (10000) // maximum number of IDs in application
|
||||
#define CONTROLS_BORDER_WIDTH (1) // border width
|
||||
#define CONTROLS_SUBWINDOW_GAP (3) // gap between sub-windows along the Y axis
|
||||
#define CONTROLS_DRAG_SPACING (50) // sensitivity threshold for dragging
|
||||
#define CONTROLS_DBL_CLICK_TIME (100) // double click interval
|
||||
//--- BmpButton
|
||||
#define CONTROLS_BUTTON_SIZE (16) // default size of button (16 x 16)
|
||||
//--- Scrolls
|
||||
#define CONTROLS_SCROLL_SIZE (18) // default lateral size of scrollbar
|
||||
#define CONTROLS_SCROLL_THUMB_SIZE (22) // default length of scroll box
|
||||
//--- RadioButton
|
||||
#define CONTROLS_RADIO_BUTTON_X_OFF (3) // X offset of radio button (for RadioButton)
|
||||
#define CONTROLS_RADIO_BUTTON_Y_OFF (3) // Y offset of radio button (for RadioButton)
|
||||
#define CONTROLS_RADIO_LABEL_X_OFF (20) // X offset of label (for RadioButton)
|
||||
#define CONTROLS_RADIO_LABEL_Y_OFF (0) // Y offset of label (for RadioButton)
|
||||
//--- CheckBox
|
||||
#define CONTROLS_CHECK_BUTTON_X_OFF (3) // X offset of check button (for CheckBox)
|
||||
#define CONTROLS_CHECK_BUTTON_Y_OFF (3) // Y offset of check button (for CheckBox)
|
||||
#define CONTROLS_CHECK_LABEL_X_OFF (20) // X offset of label (for CheckBox)
|
||||
#define CONTROLS_CHECK_LABEL_Y_OFF (0) // Y offset of label (for CheckBox)
|
||||
//--- Spin
|
||||
#define CONTROLS_SPIN_BUTTON_X_OFF (2) // X offset of button from right (for SpinEdit)
|
||||
#define CONTROLS_SPIN_MIN_HEIGHT (18) // minimal height (for SpinEdit)
|
||||
#define CONTROLS_SPIN_BUTTON_SIZE (8) // default size of button (16 x 8) (for SpinEdit)
|
||||
//--- Combo
|
||||
#define CONTROLS_COMBO_BUTTON_X_OFF (2) // X offset of button from right (for ComboBox)
|
||||
#define CONTROLS_COMBO_MIN_HEIGHT (18) // minimal height (for ComboBox)
|
||||
#define CONTROLS_COMBO_ITEM_HEIGHT (18) // height of combo box item (for ComboBox)
|
||||
#define CONTROLS_COMBO_ITEMS_VIEW (8) // number of items in combo box (for ComboBox)
|
||||
//--- ListView
|
||||
#define CONTROLS_LIST_ITEM_HEIGHT (18) // height of list item (for ListView)
|
||||
//--- Dialog
|
||||
#define CONTROLS_DIALOG_CAPTION_HEIGHT (22) // height of dialog header
|
||||
#define CONTROLS_DIALOG_BUTTON_OFF (3) // offset of dialog buttons
|
||||
#define CONTROLS_DIALOG_CLIENT_OFF (2) // offset of dialog client area
|
||||
#define CONTROLS_DIALOG_MINIMIZE_LEFT (10) // left coordinate of dialog in minimized state
|
||||
#define CONTROLS_DIALOG_MINIMIZE_TOP (10) // top coordinate of dialog in minimized state
|
||||
#define CONTROLS_DIALOG_MINIMIZE_WIDTH (100) // width of dialog in minimized state
|
||||
#define CONTROLS_DIALOG_MINIMIZE_HEIGHT (4*CONTROLS_BORDER_WIDTH+CONTROLS_DIALOG_CAPTION_HEIGHT) // height of dialog in minimized state
|
||||
//+------------------------------------------------------------------+
|
||||
//| Macro |
|
||||
//+------------------------------------------------------------------+
|
||||
//--- check properties
|
||||
#define IS_CAN_DBL_CLICK ((m_prop_flags&WND_PROP_FLAG_CAN_DBL_CLICK)!=0)
|
||||
#define IS_CAN_DRAG ((m_prop_flags&WND_PROP_FLAG_CAN_DRAG)!=0)
|
||||
#define IS_CLICKS_BY_PRESS ((m_prop_flags&WND_PROP_FLAG_CLICKS_BY_PRESS)!=0)
|
||||
#define IS_CAN_LOCK ((m_prop_flags&WND_PROP_FLAG_CAN_LOCK)!=0)
|
||||
#define IS_READ_ONLY ((m_prop_flags&WND_PROP_FLAG_READ_ONLY)!=0)
|
||||
//--- check state
|
||||
#define IS_ENABLED ((m_state_flags&WND_STATE_FLAG_ENABLE)!=0)
|
||||
#define IS_VISIBLE ((m_state_flags&WND_STATE_FLAG_VISIBLE)!=0)
|
||||
#define IS_ACTIVE ((m_state_flags&WND_STATE_FLAG_ACTIVE)!=0)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Macro of event handling map |
|
||||
//+------------------------------------------------------------------+
|
||||
#define INTERNAL_EVENT (-1)
|
||||
//--- beginning of map
|
||||
#define EVENT_MAP_BEGIN(class_name) bool class_name::OnEvent(const int id,const long& lparam,const double& dparam,const string& sparam) {
|
||||
//--- end of map
|
||||
#define EVENT_MAP_END(parent_class_name) return(parent_class_name::OnEvent(id,lparam,dparam,sparam)); }
|
||||
//--- event handling by numeric ID
|
||||
#define ON_EVENT(event,control,handler) if(id==(event+CHARTEVENT_CUSTOM) && lparam==control.Id()) { handler(); return(true); }
|
||||
//--- event handling by numeric ID by pointer of control
|
||||
#define ON_EVENT_PTR(event,control,handler) if(control!=NULL && id==(event+CHARTEVENT_CUSTOM) && lparam==control.Id()) { handler(); return(true); }
|
||||
//--- event handling without ID analysis
|
||||
#define ON_NO_ID_EVENT(event,handler) if(id==(event+CHARTEVENT_CUSTOM)) { return(handler()); }
|
||||
//--- event handling by row ID
|
||||
#define ON_NAMED_EVENT(event,control,handler) if(id==(event+CHARTEVENT_CUSTOM) && sparam==control.Name()) { handler(); return(true); }
|
||||
//--- handling of indexed event
|
||||
#define ON_INDEXED_EVENT(event,controls,handler) { int total=ArraySize(controls); for(int i=0;i<total;i++) if(id==(event+CHARTEVENT_CUSTOM) && lparam==controls[i].Id()) return(handler(i)); }
|
||||
//--- handling of external event
|
||||
#define ON_EXTERNAL_EVENT(event,handler) if(id==(event+CHARTEVENT_CUSTOM)) { handler(lparam,dparam,sparam); return(true); }
|
||||
//+------------------------------------------------------------------+
|
||||
//| Events |
|
||||
//+------------------------------------------------------------------+
|
||||
#define ON_CLICK (0) // clicking on control event
|
||||
#define ON_DBL_CLICK (1) // double clicking on control event
|
||||
#define ON_SHOW (2) // showing control event
|
||||
#define ON_HIDE (3) // hiding control event
|
||||
#define ON_CHANGE (4) // changing control event
|
||||
#define ON_START_EDIT (5) // start of editing event
|
||||
#define ON_END_EDIT (6) // end of editing event
|
||||
#define ON_SCROLL_INC (7) // increment of scrollbar event
|
||||
#define ON_SCROLL_DEC (8) // decrement of scrollbar event
|
||||
#define ON_MOUSE_FOCUS_SET (9) // the "mouse cursor entered the control" event
|
||||
#define ON_MOUSE_FOCUS_KILL (10) // the "mouse cursor exited the control" event
|
||||
#define ON_DRAG_START (11) // the "control dragging start" event
|
||||
#define ON_DRAG_PROCESS (12) // the "control is being dragged" event
|
||||
#define ON_DRAG_END (13) // the "control dragging end" event
|
||||
#define ON_BRING_TO_TOP (14) // the "mouse events priority increase" event
|
||||
#define ON_APP_CLOSE (100) // "closing the application" event
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,971 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Dialog.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndContainer.mqh"
|
||||
#include "WndClient.mqh"
|
||||
#include "Panel.mqh"
|
||||
#include "Edit.mqh"
|
||||
#include "BmpButton.mqh"
|
||||
#include <Charts\Chart.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resources |
|
||||
//+------------------------------------------------------------------+
|
||||
#resource "res\\Close.bmp"
|
||||
#resource "res\\Restore.bmp"
|
||||
#resource "res\\Turn.bmp"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CDialog |
|
||||
//| Usage: base class to create dialog boxes |
|
||||
//| and indicator panels |
|
||||
//+------------------------------------------------------------------+
|
||||
class CDialog : public CWndContainer
|
||||
{
|
||||
private:
|
||||
//--- dependent controls
|
||||
CPanel m_white_border; // the "white border" object
|
||||
CPanel m_background; // the background object
|
||||
CEdit m_caption; // the window title object
|
||||
CBmpButton m_button_close; // the "Close" button object
|
||||
CWndClient m_client_area; // the client area object
|
||||
|
||||
protected:
|
||||
//--- flags
|
||||
bool m_panel_flag; // the "panel in a separate window" flag
|
||||
//--- flags
|
||||
bool m_minimized; // "create in minimized state" flag
|
||||
//--- additional areas
|
||||
CRect m_min_rect; // minimal area coordinates
|
||||
CRect m_norm_rect; // normal area coordinates
|
||||
|
||||
public:
|
||||
CDialog(void);
|
||||
~CDialog(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- set up
|
||||
string Caption(void) const { return(m_caption.Text()); }
|
||||
bool Caption(const string text) { return(m_caption.Text(text)); }
|
||||
//--- fill
|
||||
bool Add(CWnd *control);
|
||||
bool Add(CWnd &control);
|
||||
//--- methods for working with files
|
||||
virtual bool Save(const int file_handle);
|
||||
virtual bool Load(const int file_handle);
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
virtual bool CreateWhiteBorder(void);
|
||||
virtual bool CreateBackground(void);
|
||||
virtual bool CreateCaption(void);
|
||||
virtual bool CreateButtonClose(void);
|
||||
virtual bool CreateClientArea(void);
|
||||
//--- handlers of the dependent controls events
|
||||
virtual void OnClickCaption(void);
|
||||
virtual void OnClickButtonClose(void);
|
||||
//--- access properties of caption
|
||||
void CaptionAlignment(const int flags,const int left,const int top,const int right,const int bottom)
|
||||
{ m_caption.Alignment(flags,left,top,right,bottom); }
|
||||
//--- access properties of client area
|
||||
bool ClientAreaVisible(const bool visible) { return(m_client_area.Visible(visible)); }
|
||||
int ClientAreaLeft(void) const { return(m_client_area.Left()); }
|
||||
int ClientAreaTop(void) const { return(m_client_area.Top()); }
|
||||
int ClientAreaRight(void) const { return(m_client_area.Right()); }
|
||||
int ClientAreaBottom(void) const { return(m_client_area.Bottom()); }
|
||||
int ClientAreaWidth(void) const { return(m_client_area.Width()); }
|
||||
int ClientAreaHeight(void) const { return(m_client_area.Height()); }
|
||||
//--- handlers of drag
|
||||
virtual bool OnDialogDragStart(void);
|
||||
virtual bool OnDialogDragProcess(void);
|
||||
virtual bool OnDialogDragEnd(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of events |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_BEGIN(CDialog)
|
||||
ON_EVENT(ON_CLICK,m_button_close,OnClickButtonClose)
|
||||
ON_EVENT(ON_CLICK,m_caption,OnClickCaption)
|
||||
ON_EVENT(ON_DRAG_START,m_caption,OnDialogDragStart)
|
||||
ON_EVENT_PTR(ON_DRAG_PROCESS,m_drag_object,OnDialogDragProcess)
|
||||
ON_EVENT_PTR(ON_DRAG_END,m_drag_object,OnDialogDragEnd)
|
||||
EVENT_MAP_END(CWndContainer)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CDialog::CDialog(void) : m_panel_flag(false),
|
||||
m_minimized(false)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CDialog::~CDialog(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- call method of parent class
|
||||
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create dependent controls
|
||||
if(!m_panel_flag && !CreateWhiteBorder())
|
||||
return(false);
|
||||
if(!CreateBackground())
|
||||
return(false);
|
||||
if(!CreateCaption())
|
||||
return(false);
|
||||
if(!CreateButtonClose())
|
||||
return(false);
|
||||
if(!CreateClientArea())
|
||||
return(false);
|
||||
//--- set up additional areas
|
||||
m_norm_rect.SetBound(m_rect);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Add control to the client area (by pointer) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDialog::Add(CWnd *control)
|
||||
{
|
||||
return(m_client_area.Add(control));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Add control to the client area (by reference) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDialog::Add(CWnd &control)
|
||||
{
|
||||
return(m_client_area.Add(control));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Save |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDialog::Save(const int file_handle)
|
||||
{
|
||||
//--- check
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//--- save
|
||||
FileWriteStruct(file_handle,m_norm_rect);
|
||||
FileWriteInteger(file_handle,m_min_rect.left);
|
||||
FileWriteInteger(file_handle,m_min_rect.top);
|
||||
FileWriteInteger(file_handle,m_minimized);
|
||||
//--- result
|
||||
return(CWndContainer::Save(file_handle));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Load |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDialog::Load(const int file_handle)
|
||||
{
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//--- load
|
||||
if(!FileIsEnding(file_handle))
|
||||
{
|
||||
FileReadStruct(file_handle,m_norm_rect);
|
||||
int left=FileReadInteger(file_handle);
|
||||
int top=FileReadInteger(file_handle);
|
||||
m_min_rect.Move(left,top);
|
||||
m_minimized=FileReadInteger(file_handle);
|
||||
}
|
||||
//--- result
|
||||
return(CWndContainer::Load(file_handle));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create "white border" |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDialog::CreateWhiteBorder(void)
|
||||
{
|
||||
//--- coordinates
|
||||
int x1=0;
|
||||
int y1=0;
|
||||
int x2=Width();
|
||||
int y2=Height();
|
||||
//--- create
|
||||
if(!m_white_border.Create(m_chart_id,m_name+"Border",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_white_border.ColorBackground(CONTROLS_DIALOG_COLOR_BG))
|
||||
return(false);
|
||||
if(!m_white_border.ColorBorder(CONTROLS_DIALOG_COLOR_BORDER_LIGHT))
|
||||
return(false);
|
||||
if(!CWndContainer::Add(m_white_border))
|
||||
return(false);
|
||||
m_white_border.Alignment(WND_ALIGN_CLIENT,0,0,0,0);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create background |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDialog::CreateBackground(void)
|
||||
{
|
||||
int off=(m_panel_flag) ? 0:CONTROLS_BORDER_WIDTH;
|
||||
//--- coordinates
|
||||
int x1=off;
|
||||
int y1=off;
|
||||
int x2=Width()-off;
|
||||
int y2=Height()-off;
|
||||
//--- create
|
||||
if(!m_background.Create(m_chart_id,m_name+"Back",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_background.ColorBackground(CONTROLS_DIALOG_COLOR_BG))
|
||||
return(false);
|
||||
color border=(m_panel_flag) ? CONTROLS_DIALOG_COLOR_BG : CONTROLS_DIALOG_COLOR_BORDER_DARK;
|
||||
if(!m_background.ColorBorder(border))
|
||||
return(false);
|
||||
if(!CWndContainer::Add(m_background))
|
||||
return(false);
|
||||
m_background.Alignment(WND_ALIGN_CLIENT,off,off,off,off);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create window title |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDialog::CreateCaption(void)
|
||||
{
|
||||
int off=(m_panel_flag) ? 0:2*CONTROLS_BORDER_WIDTH;
|
||||
//--- coordinates
|
||||
int x1=off;
|
||||
int y1=off;
|
||||
int x2=Width()-off;
|
||||
int y2=y1+CONTROLS_DIALOG_CAPTION_HEIGHT;
|
||||
//--- create
|
||||
if(!m_caption.Create(m_chart_id,m_name+"Caption",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_caption.Color(CONTROLS_DIALOG_COLOR_CAPTION_TEXT))
|
||||
return(false);
|
||||
if(!m_caption.ColorBackground(CONTROLS_DIALOG_COLOR_BG))
|
||||
return(false);
|
||||
if(!m_caption.ColorBorder(CONTROLS_DIALOG_COLOR_BG))
|
||||
return(false);
|
||||
if(!m_caption.ReadOnly(true))
|
||||
return(false);
|
||||
if(!m_caption.Text(m_name))
|
||||
return(false);
|
||||
if(!CWndContainer::Add(m_caption))
|
||||
return(false);
|
||||
m_caption.Alignment(WND_ALIGN_WIDTH,off,0,off,0);
|
||||
if(!m_panel_flag)
|
||||
m_caption.PropFlags(WND_PROP_FLAG_CAN_DRAG);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create the "Close" button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDialog::CreateButtonClose(void)
|
||||
{
|
||||
int off=(m_panel_flag) ? 0 : 2*CONTROLS_BORDER_WIDTH;
|
||||
//--- coordinates
|
||||
int x1=Width()-off-(CONTROLS_BUTTON_SIZE+CONTROLS_DIALOG_BUTTON_OFF);
|
||||
int y1=off+CONTROLS_DIALOG_BUTTON_OFF;
|
||||
int x2=x1+CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_BUTTON_SIZE;
|
||||
//--- create
|
||||
if(!m_button_close.Create(m_chart_id,m_name+"Close",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_button_close.BmpNames("::res\\Close.bmp"))
|
||||
return(false);
|
||||
if(!CWndContainer::Add(m_button_close))
|
||||
return(false);
|
||||
m_button_close.Alignment(WND_ALIGN_RIGHT,0,0,off+CONTROLS_DIALOG_BUTTON_OFF,0);
|
||||
//--- change caption
|
||||
CaptionAlignment(WND_ALIGN_WIDTH,off,0,off+(CONTROLS_BUTTON_SIZE+CONTROLS_DIALOG_BUTTON_OFF),0);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create client area |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDialog::CreateClientArea(void)
|
||||
{
|
||||
int off=(m_panel_flag) ? 0:2*CONTROLS_BORDER_WIDTH;
|
||||
//--- coordinates
|
||||
int x1=off+CONTROLS_DIALOG_CLIENT_OFF;
|
||||
int y1=off+CONTROLS_DIALOG_CAPTION_HEIGHT;
|
||||
int x2=Width()-(off+CONTROLS_DIALOG_CLIENT_OFF);
|
||||
int y2=Height()-(off+CONTROLS_DIALOG_CLIENT_OFF);
|
||||
//--- create
|
||||
if(!m_client_area.Create(m_chart_id,m_name+"Client",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_client_area.ColorBackground(CONTROLS_DIALOG_COLOR_CLIENT_BG))
|
||||
return(false);
|
||||
if(!m_client_area.ColorBorder(CONTROLS_DIALOG_COLOR_CLIENT_BORDER))
|
||||
return(false);
|
||||
CWndContainer::Add(m_client_area);
|
||||
m_client_area.Alignment(WND_ALIGN_CLIENT,x1,y1,x1,x1);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on the window title |
|
||||
//+------------------------------------------------------------------+
|
||||
void CDialog::OnClickCaption(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on the "Close" button |
|
||||
//+------------------------------------------------------------------+
|
||||
void CDialog::OnClickButtonClose(void)
|
||||
{
|
||||
Visible(false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Start dragging the dialog box |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDialog::OnDialogDragStart(void)
|
||||
{
|
||||
if(m_drag_object==NULL)
|
||||
{
|
||||
m_drag_object=new CDragWnd;
|
||||
if(m_drag_object==NULL)
|
||||
return(false);
|
||||
}
|
||||
//--- calculate coordinates
|
||||
int x1=Left()-CONTROLS_DRAG_SPACING;
|
||||
int y1=Top()-CONTROLS_DRAG_SPACING;
|
||||
int x2=Right()+CONTROLS_DRAG_SPACING;
|
||||
int y2=Bottom()+CONTROLS_DRAG_SPACING;
|
||||
//--- create
|
||||
m_drag_object.Create(m_chart_id,"",m_subwin,x1,y1,x2,y2);
|
||||
m_drag_object.PropFlags(WND_PROP_FLAG_CAN_DRAG);
|
||||
//--- constraints
|
||||
CChart chart;
|
||||
chart.Attach(m_chart_id);
|
||||
m_drag_object.Limits(-CONTROLS_DRAG_SPACING,-CONTROLS_DRAG_SPACING,
|
||||
chart.WidthInPixels()+CONTROLS_DRAG_SPACING,
|
||||
chart.HeightInPixels(m_subwin)+CONTROLS_DRAG_SPACING);
|
||||
chart.Detach();
|
||||
//--- set mouse params
|
||||
m_drag_object.MouseX(m_caption.MouseX());
|
||||
m_drag_object.MouseY(m_caption.MouseY());
|
||||
m_drag_object.MouseFlags(m_caption.MouseFlags());
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Continue dragging the dialog box |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDialog::OnDialogDragProcess(void)
|
||||
{
|
||||
//--- checking
|
||||
if(m_drag_object==NULL)
|
||||
return(false);
|
||||
//--- calculate coordinates
|
||||
int x=m_drag_object.Left()+50;
|
||||
int y=m_drag_object.Top()+50;
|
||||
//--- move dialog
|
||||
Move(x,y);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| End dragging the dialog box |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDialog::OnDialogDragEnd(void)
|
||||
{
|
||||
if(m_drag_object!=NULL)
|
||||
{
|
||||
m_caption.MouseFlags(m_drag_object.MouseFlags());
|
||||
delete m_drag_object;
|
||||
m_drag_object=NULL;
|
||||
}
|
||||
//--- set up additional areas
|
||||
if(m_minimized)
|
||||
m_min_rect.SetBound(m_rect);
|
||||
else
|
||||
m_norm_rect.SetBound(m_rect);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CAppDialog |
|
||||
//| Usage: main dialog box of MQL5 application |
|
||||
//+------------------------------------------------------------------+
|
||||
class CAppDialog : public CDialog
|
||||
{
|
||||
private:
|
||||
//--- dependent controls
|
||||
CBmpButton m_button_minmax; // the "Minimize/Maximize" button object
|
||||
//--- variables
|
||||
string m_program_name; // name of program
|
||||
string m_instance_id; // unique string ID
|
||||
ENUM_PROGRAM_TYPE m_program_type; // type of program
|
||||
string m_indicator_name;
|
||||
int m_deinit_reason;
|
||||
//--- for mouse
|
||||
int m_subwin_Yoff; // subwindow Y offset
|
||||
CWnd* m_focused_wnd; // pointer to object that has mouse focus
|
||||
CWnd* m_top_wnd; // pointer to object that has priority over mouse events handling
|
||||
|
||||
protected:
|
||||
CChart m_chart; // object to access chart
|
||||
|
||||
public:
|
||||
CAppDialog(void);
|
||||
~CAppDialog(void);
|
||||
//--- main application dialog creation and destroy
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
virtual void Destroy(const int reason=REASON_PROGRAM);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- dialog run
|
||||
bool Run(void);
|
||||
//--- chart events processing
|
||||
void ChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- set up
|
||||
void Minimized(const bool flag) { m_minimized=flag; }
|
||||
//--- to save/restore state
|
||||
void IniFileSave(void);
|
||||
void IniFileLoad(void);
|
||||
virtual string IniFileName(void) const;
|
||||
virtual string IniFileExt(void) const { return(".dat"); }
|
||||
virtual bool Load(const int file_handle);
|
||||
virtual bool Save(const int file_handle);
|
||||
|
||||
private:
|
||||
bool CreateCommon(const long chart,const string name,const int subwin);
|
||||
bool CreateExpert(const int x1,const int y1,const int x2,const int y2);
|
||||
bool CreateIndicator(const int x1,const int y1,const int x2,const int y2);
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
virtual bool CreateButtonMinMax(void);
|
||||
//--- handlers of the dependent controls events
|
||||
virtual void OnClickButtonClose(void);
|
||||
virtual void OnClickButtonMinMax(void);
|
||||
//--- external event handlers
|
||||
virtual void OnAnotherApplicationClose(const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- methods
|
||||
virtual bool Rebound(const CRect &rect);
|
||||
virtual void Minimize(void);
|
||||
virtual void Maximize(void);
|
||||
string CreateInstanceId(void);
|
||||
string ProgramName(void) const { return(m_program_name); }
|
||||
void SubwinOff(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of events |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_BEGIN(CAppDialog)
|
||||
ON_EVENT(ON_CLICK,m_button_minmax,OnClickButtonMinMax)
|
||||
ON_EXTERNAL_EVENT(ON_APP_CLOSE,OnAnotherApplicationClose)
|
||||
EVENT_MAP_END(CDialog)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CAppDialog::CAppDialog(void) : m_program_type(WRONG_VALUE),
|
||||
m_deinit_reason(WRONG_VALUE),
|
||||
m_subwin_Yoff(0),
|
||||
m_focused_wnd(NULL),
|
||||
m_top_wnd(NULL)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CAppDialog::~CAppDialog(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Application dialog initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CAppDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
if(!CreateCommon(chart,name,subwin))
|
||||
return(false);
|
||||
//---
|
||||
switch(m_program_type)
|
||||
{
|
||||
case PROGRAM_EXPERT:
|
||||
if(!CreateExpert(x1,y1,x2,y2))
|
||||
return(false);
|
||||
break;
|
||||
case PROGRAM_INDICATOR:
|
||||
if(!CreateIndicator(x1,y1,x2,y2))
|
||||
return(false);
|
||||
break;
|
||||
default:
|
||||
Print("CAppDialog: invalid program type");
|
||||
return(false);
|
||||
}
|
||||
//--- Title of dialog window
|
||||
if(!Caption(m_program_name))
|
||||
return(false);
|
||||
//--- create dependent controls
|
||||
if(!CreateButtonMinMax())
|
||||
return(false);
|
||||
//--- get subwindow offset
|
||||
SubwinOff();
|
||||
//--- if flag is set, minimize the dialog
|
||||
if(m_minimized)
|
||||
Minimize();
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize common area |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CAppDialog::CreateCommon(const long chart,const string name,const int subwin)
|
||||
{
|
||||
//--- save parameters
|
||||
m_chart_id =chart;
|
||||
m_name =name;
|
||||
m_subwin =subwin;
|
||||
m_program_name =name;
|
||||
m_deinit_reason=WRONG_VALUE;
|
||||
//--- get unique ID
|
||||
m_instance_id=CreateInstanceId();
|
||||
//--- initialize chart object
|
||||
m_chart.Attach(chart);
|
||||
//--- determine type of program
|
||||
m_program_type=(ENUM_PROGRAM_TYPE)MQLInfoInteger(MQL_PROGRAM_TYPE);
|
||||
//--- specify object and mouse events
|
||||
if(!m_chart.EventObjectCreate() || !m_chart.EventObjectDelete() || !m_chart.EventMouseMove())
|
||||
{
|
||||
Print("CAppDialog: object events specify error");
|
||||
m_chart.Detach();
|
||||
return(false);
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize in Expert Advisor |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CAppDialog::CreateExpert(const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- EA works only in main window
|
||||
m_subwin=0;
|
||||
//--- geometry for the minimized state
|
||||
m_min_rect.SetBound(CONTROLS_DIALOG_MINIMIZE_LEFT,
|
||||
CONTROLS_DIALOG_MINIMIZE_TOP,
|
||||
CONTROLS_DIALOG_MINIMIZE_LEFT+CONTROLS_DIALOG_MINIMIZE_WIDTH,
|
||||
CONTROLS_DIALOG_MINIMIZE_TOP+CONTROLS_DIALOG_MINIMIZE_HEIGHT);
|
||||
//--- call method of the parent class
|
||||
if(!CDialog::Create(m_chart.ChartId(),m_instance_id,m_subwin,x1,y1,x2,y2))
|
||||
{
|
||||
Print("CAppDialog: expert dialog create error");
|
||||
m_chart.Detach();
|
||||
return(false);
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize in Indicator |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CAppDialog::CreateIndicator(const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
int width=m_chart.WidthInPixels();
|
||||
//--- geometry for the minimized state
|
||||
m_min_rect.LeftTop(0,0);
|
||||
m_min_rect.Width(width);
|
||||
m_min_rect.Height(CONTROLS_DIALOG_MINIMIZE_HEIGHT-2*CONTROLS_BORDER_WIDTH);
|
||||
//--- determine subwindow
|
||||
m_subwin=ChartWindowFind();
|
||||
if(m_subwin==-1)
|
||||
{
|
||||
Print("CAppDialog: find subwindow error");
|
||||
m_chart.Detach();
|
||||
return(false);
|
||||
}
|
||||
//---
|
||||
int total=ChartIndicatorsTotal(m_chart.ChartId(),m_subwin);
|
||||
m_indicator_name=ChartIndicatorName(m_chart.ChartId(),m_subwin,total-1);
|
||||
//--- if subwindow number is 0 (main window), then our program is
|
||||
//--- not an indicator panel, but is an indicator with built-in settings dialog
|
||||
//--- dialog of such an indicator should behave as an Expert Advisor dialog
|
||||
if(m_subwin==0)
|
||||
return(CreateExpert(x1,y1,x2,y2));
|
||||
//--- if subwindow number is not 0, then our program is an indicator panel
|
||||
//--- check if subwindow is not occupied by other indicators
|
||||
if(total!=1)
|
||||
{
|
||||
Print("CAppDialog: subwindow busy");
|
||||
ChartIndicatorDelete(m_chart.ChartId(),m_subwin,ChartIndicatorName(m_chart.ChartId(),m_subwin,total-1));
|
||||
m_chart.Detach();
|
||||
return(false);
|
||||
}
|
||||
//--- resize subwindow by dialog height
|
||||
if(!IndicatorSetInteger(INDICATOR_HEIGHT,(y2-y1)+1))
|
||||
{
|
||||
Print("CAppDialog: subwindow resize error");
|
||||
ChartIndicatorDelete(m_chart.ChartId(),m_subwin,ChartIndicatorName(m_chart.ChartId(),m_subwin,total-1));
|
||||
m_chart.Detach();
|
||||
return(false);
|
||||
}
|
||||
//--- indicator short name
|
||||
m_indicator_name=m_program_name+IntegerToString(m_subwin);
|
||||
if(!IndicatorSetString(INDICATOR_SHORTNAME,m_indicator_name))
|
||||
{
|
||||
Print("CAppDialog: shortname error");
|
||||
ChartIndicatorDelete(m_chart.ChartId(),m_subwin,ChartIndicatorName(m_chart.ChartId(),m_subwin,total-1));
|
||||
m_chart.Detach();
|
||||
return(false);
|
||||
}
|
||||
//--- set flag
|
||||
m_panel_flag=true;
|
||||
//--- call method of the parent class
|
||||
if(!CDialog::Create(m_chart.ChartId(),m_instance_id,m_subwin,0,0,width,y2-y1))
|
||||
{
|
||||
Print("CAppDialog: indicator dialog create error");
|
||||
ChartIndicatorDelete(m_chart.ChartId(),m_subwin,ChartIndicatorName(m_chart.ChartId(),m_subwin,total-1));
|
||||
m_chart.Detach();
|
||||
return(false);
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Application dialog deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void CAppDialog::Destroy(const int reason)
|
||||
{
|
||||
//--- destroyed already?
|
||||
if(m_deinit_reason!=WRONG_VALUE)
|
||||
return;
|
||||
//---
|
||||
m_deinit_reason=reason;
|
||||
IniFileSave();
|
||||
//--- detach chart object from chart
|
||||
m_chart.Detach();
|
||||
//--- call parent destroy
|
||||
CDialog::Destroy();
|
||||
//---
|
||||
if(reason==REASON_PROGRAM)
|
||||
{
|
||||
if(m_program_type==PROGRAM_EXPERT)
|
||||
ExpertRemove();
|
||||
if(m_program_type==PROGRAM_INDICATOR)
|
||||
ChartIndicatorDelete(m_chart_id,m_subwin,m_indicator_name);
|
||||
}
|
||||
//--- send message
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_APP_CLOSE,m_subwin,0.0,m_program_name);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Calculate subwindow offset |
|
||||
//+------------------------------------------------------------------+
|
||||
void CAppDialog::SubwinOff(void)
|
||||
{
|
||||
m_subwin_Yoff=m_chart.SubwindowY(m_subwin);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create the "Minimize/Maximize" button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CAppDialog::CreateButtonMinMax(void)
|
||||
{
|
||||
int off=(m_panel_flag) ? 0:2*CONTROLS_BORDER_WIDTH;
|
||||
//--- coordinates
|
||||
int x1=Width()-off-2*(CONTROLS_BUTTON_SIZE+CONTROLS_DIALOG_BUTTON_OFF);
|
||||
int y1=off+CONTROLS_DIALOG_BUTTON_OFF;
|
||||
int x2=x1+CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_BUTTON_SIZE;
|
||||
//--- create
|
||||
if(!m_button_minmax.Create(m_chart_id,m_name+"MinMax",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_button_minmax.BmpNames("::res\\Turn.bmp","::res\\Restore.bmp"))
|
||||
return(false);
|
||||
if(!CWndContainer::Add(m_button_minmax))
|
||||
return(false);
|
||||
m_button_minmax.Locking(true);
|
||||
m_button_minmax.Alignment(WND_ALIGN_RIGHT,0,0,off+CONTROLS_BUTTON_SIZE+2*CONTROLS_DIALOG_BUTTON_OFF,0);
|
||||
//--- change caption
|
||||
CaptionAlignment(WND_ALIGN_WIDTH,off,0,off+2*(CONTROLS_BUTTON_SIZE+CONTROLS_DIALOG_BUTTON_OFF),0);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Charts event processing |
|
||||
//+------------------------------------------------------------------+
|
||||
void CAppDialog::ChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
|
||||
{
|
||||
int mouse_x=(int)lparam;
|
||||
int mouse_y=(int)dparam-m_subwin_Yoff;
|
||||
//--- separate mouse events from others
|
||||
switch(id)
|
||||
{
|
||||
case CHARTEVENT_CHART_CHANGE:
|
||||
//--- assumed that the CHARTEVENT_CHART_CHANGE event can handle only the application dialog
|
||||
break;
|
||||
case CHARTEVENT_OBJECT_CLICK:
|
||||
//--- we won't handle the CHARTEVENT_OBJECT_CLICK event, as we are working with the CHARTEVENT_MOUSE_MOVE events
|
||||
return;
|
||||
case CHARTEVENT_CUSTOM+ON_MOUSE_FOCUS_SET:
|
||||
//--- the CHARTEVENT_CUSTOM + ON_MOUSE_FOCUS_SET event
|
||||
if(CheckPointer(m_focused_wnd)!=POINTER_INVALID)
|
||||
{
|
||||
//--- if there is an element with focus, try to take its focus away
|
||||
if(!m_focused_wnd.MouseFocusKill(lparam))
|
||||
return;
|
||||
}
|
||||
m_focused_wnd=ControlFind(lparam);
|
||||
return;
|
||||
case CHARTEVENT_CUSTOM+ON_BRING_TO_TOP:
|
||||
m_top_wnd=ControlFind(lparam);
|
||||
return;
|
||||
case CHARTEVENT_MOUSE_MOVE:
|
||||
//--- the CHARTEVENT_MOUSE_MOVE event
|
||||
if(CheckPointer(m_top_wnd)!=POINTER_INVALID)
|
||||
{
|
||||
//--- if a priority element already exists, pass control to it
|
||||
if(m_top_wnd.OnMouseEvent(mouse_x,mouse_y,(int)StringToInteger(sparam)))
|
||||
{
|
||||
//--- event handled
|
||||
m_chart.Redraw();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(OnMouseEvent(mouse_x,mouse_y,(int)StringToInteger(sparam)))
|
||||
m_chart.Redraw();
|
||||
return;
|
||||
default:
|
||||
//--- call event processing and redraw chart if event handled
|
||||
if(OnEvent(id,lparam,dparam,sparam))
|
||||
m_chart.Redraw();
|
||||
return;
|
||||
}
|
||||
//--- if event was not handled, try to handle the CHARTEVENT_CHART_CHANGE event
|
||||
if(id==CHARTEVENT_CHART_CHANGE)
|
||||
{
|
||||
//--- if subwindow number is not 0, and dialog subwindow has changed its number, then restart
|
||||
if(m_subwin!=0 && m_subwin!=ChartWindowFind())
|
||||
{
|
||||
long fiction=1;
|
||||
OnAnotherApplicationClose(fiction,dparam,sparam);
|
||||
}
|
||||
//--- if subwindow height is less that dialog height, minimize application window (always)
|
||||
if(m_chart.HeightInPixels(m_subwin)<Height()+CONTROLS_BORDER_WIDTH)
|
||||
{
|
||||
m_button_minmax.Pressed(true);
|
||||
Minimize();
|
||||
m_chart.Redraw();
|
||||
}
|
||||
//--- if chart width is less that dialog width, and subwindow number is not 0, try to modify dialog width
|
||||
if(m_chart.WidthInPixels()!=Width() && m_subwin!=0)
|
||||
{
|
||||
Width(m_chart.WidthInPixels());
|
||||
m_chart.Redraw();
|
||||
}
|
||||
//--- get subwindow offset
|
||||
SubwinOff();
|
||||
return;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Run application |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CAppDialog::Run(void)
|
||||
{
|
||||
//--- redraw chart for dialog invalidate
|
||||
m_chart.Redraw();
|
||||
//--- here we begin to assign IDs to controls
|
||||
if(Id(m_subwin*CONTROLS_MAXIMUM_ID)>CONTROLS_MAXIMUM_ID)
|
||||
{
|
||||
Print("CAppDialog: too many objects");
|
||||
return(false);
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Stop application |
|
||||
//+------------------------------------------------------------------+
|
||||
void CAppDialog::OnClickButtonClose(void)
|
||||
{
|
||||
//--- destroy application
|
||||
Destroy();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on the "Minimize/Maximize" button |
|
||||
//+------------------------------------------------------------------+
|
||||
void CAppDialog::OnClickButtonMinMax(void)
|
||||
{
|
||||
if(m_button_minmax.Pressed())
|
||||
Minimize();
|
||||
else
|
||||
Maximize();
|
||||
//--- get subwindow offset
|
||||
SubwinOff();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resize |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CAppDialog::Rebound(const CRect &rect)
|
||||
{
|
||||
if(!Move(rect.LeftTop()))
|
||||
return(false);
|
||||
if(!Size(rect.Size()))
|
||||
return(false);
|
||||
//--- resize subwindow
|
||||
if(m_program_type==PROGRAM_INDICATOR && !IndicatorSetInteger(INDICATOR_HEIGHT,rect.Height()+1))
|
||||
{
|
||||
Print("CAppDialog: subwindow resize error");
|
||||
return(false);
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Minimize dialog window |
|
||||
//+------------------------------------------------------------------+
|
||||
void CAppDialog::Minimize(void)
|
||||
{
|
||||
//--- set flag
|
||||
m_minimized=true;
|
||||
//--- resize
|
||||
Rebound(m_min_rect);
|
||||
//--- hide client area
|
||||
ClientAreaVisible(false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Restore dialog window |
|
||||
//+------------------------------------------------------------------+
|
||||
void CAppDialog::Maximize(void)
|
||||
{
|
||||
//--- reset flag
|
||||
m_minimized=false;
|
||||
//--- resize
|
||||
Rebound(m_norm_rect);
|
||||
//--- show client area
|
||||
ClientAreaVisible(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create unique prefix for object names |
|
||||
//+------------------------------------------------------------------+
|
||||
string CAppDialog::CreateInstanceId(void)
|
||||
{
|
||||
return(IntegerToString(rand(),5,'0'));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the ON_APP_CLOSE external event |
|
||||
//+------------------------------------------------------------------+
|
||||
void CAppDialog::OnAnotherApplicationClose(const long &lparam,const double &dparam,const string &sparam)
|
||||
{
|
||||
//--- exit if we are in the main window
|
||||
if(m_subwin==0)
|
||||
return;
|
||||
//--- exit if external program was closed in main window
|
||||
if(lparam==0)
|
||||
return;
|
||||
//--- get subwindow offset
|
||||
SubwinOff();
|
||||
//--- exit if external program was closed in subwindow with greater number
|
||||
if(lparam>=m_subwin)
|
||||
return;
|
||||
//--- after all the checks we must change the subwindow
|
||||
//--- get the new number of subwindow
|
||||
m_subwin=ChartWindowFind();
|
||||
//--- change short name
|
||||
m_indicator_name=m_program_name+IntegerToString(m_subwin);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,m_indicator_name);
|
||||
//--- change dialog title
|
||||
Caption(m_program_name);
|
||||
//--- reassign IDs
|
||||
Run();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Save the current state of the program |
|
||||
//+------------------------------------------------------------------+
|
||||
void CAppDialog::IniFileSave(void)
|
||||
{
|
||||
string filename=IniFileName()+IniFileExt();
|
||||
int handle=FileOpen(filename,FILE_WRITE|FILE_BIN|FILE_ANSI);
|
||||
//---
|
||||
if(handle!=INVALID_HANDLE)
|
||||
{
|
||||
Save(handle);
|
||||
FileClose(handle);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Read the previous state of the program |
|
||||
//+------------------------------------------------------------------+
|
||||
void CAppDialog::IniFileLoad(void)
|
||||
{
|
||||
string filename=IniFileName()+IniFileExt();
|
||||
int handle=FileOpen(filename,FILE_READ|FILE_BIN|FILE_ANSI);
|
||||
//---
|
||||
if(handle!=INVALID_HANDLE)
|
||||
{
|
||||
Load(handle);
|
||||
FileClose(handle);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Generate the filename |
|
||||
//+------------------------------------------------------------------+
|
||||
string CAppDialog::IniFileName(void) const
|
||||
{
|
||||
string name;
|
||||
//---
|
||||
name=(m_indicator_name!=NULL) ? m_indicator_name : m_program_name;
|
||||
//---
|
||||
name+="_"+Symbol();
|
||||
name+="_Ini";
|
||||
//---
|
||||
return(name);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Load data |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CAppDialog::Load(const int file_handle)
|
||||
{
|
||||
if(CDialog::Load(file_handle))
|
||||
{
|
||||
if(m_minimized)
|
||||
{
|
||||
m_button_minmax.Pressed(true);
|
||||
Minimize();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_button_minmax.Pressed(false);
|
||||
Maximize();
|
||||
}
|
||||
int prev_deinit_reason=FileReadInteger(file_handle);
|
||||
if(prev_deinit_reason==REASON_CHARTCLOSE || prev_deinit_reason==REASON_CLOSE)
|
||||
{
|
||||
//--- if the previous time program ended after closing the chart window,
|
||||
//--- delete object left since the last start of the program
|
||||
string prev_instance_id=IntegerToString(FileReadInteger(file_handle),5,'0');
|
||||
if(prev_instance_id!=m_instance_id)
|
||||
{
|
||||
long chart_id=m_chart.ChartId();
|
||||
int total=ObjectsTotal(chart_id,m_subwin);
|
||||
for(int i=total-1;i>=0;i--)
|
||||
{
|
||||
string obj_name=ObjectName(chart_id,i,m_subwin);
|
||||
if(StringFind(obj_name,prev_instance_id)==0)
|
||||
ObjectDelete(chart_id,obj_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
//--- failure
|
||||
return(false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Save data |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CAppDialog::Save(const int file_handle)
|
||||
{
|
||||
if(CDialog::Save(file_handle))
|
||||
{
|
||||
FileWriteInteger(file_handle,m_deinit_reason);
|
||||
FileWriteInteger(file_handle,(int)StringToInteger(m_instance_id));
|
||||
return(true);
|
||||
}
|
||||
//--- failure
|
||||
return(false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,188 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Edit.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndObj.mqh"
|
||||
#include <ChartObjects\ChartObjectsTxtControls.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CEdit |
|
||||
//| Usage: control that is displayed by |
|
||||
//| the CChartObjectEdit object |
|
||||
//+------------------------------------------------------------------+
|
||||
class CEdit : public CWndObj
|
||||
{
|
||||
private:
|
||||
CChartObjectEdit m_edit; // chart object
|
||||
//--- parameters of the chart object
|
||||
bool m_read_only; // "read-only" mode flag
|
||||
ENUM_ALIGN_MODE m_align_mode; // align mode
|
||||
|
||||
public:
|
||||
CEdit(void);
|
||||
~CEdit(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- parameters of the chart object
|
||||
bool ReadOnly(void) const { return(m_read_only); }
|
||||
bool ReadOnly(const bool flag);
|
||||
ENUM_ALIGN_MODE TextAlign(void) const { return(m_align_mode); }
|
||||
bool TextAlign(const ENUM_ALIGN_MODE align);
|
||||
//--- data access
|
||||
string Text(void) const { return(m_edit.Description()); }
|
||||
bool Text(const string value) { return(CWndObj::Text(value)); }
|
||||
|
||||
protected:
|
||||
//--- handlers of object events
|
||||
virtual bool OnObjectEndEdit(void);
|
||||
//--- handlers of object settings
|
||||
virtual bool OnSetText(void) { return(m_edit.Description(m_text)); }
|
||||
virtual bool OnSetColor(void) { return(m_edit.Color(m_color)); }
|
||||
virtual bool OnSetColorBackground(void) { return(m_edit.BackColor(m_color_background)); }
|
||||
virtual bool OnSetColorBorder(void) { return(m_edit.BorderColor(m_color_border)); }
|
||||
virtual bool OnSetFont(void) { return(m_edit.Font(m_font)); }
|
||||
virtual bool OnSetFontSize(void) { return(m_edit.FontSize(m_font_size)); }
|
||||
virtual bool OnSetZOrder(void) { return(m_edit.Z_Order(m_zorder)); }
|
||||
//--- internal event handlers
|
||||
virtual bool OnCreate(void);
|
||||
virtual bool OnShow(void);
|
||||
virtual bool OnHide(void);
|
||||
virtual bool OnMove(void);
|
||||
virtual bool OnResize(void);
|
||||
virtual bool OnChange(void);
|
||||
virtual bool OnClick(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CEdit::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
|
||||
{
|
||||
if(m_name==sparam && id==CHARTEVENT_OBJECT_ENDEDIT)
|
||||
return(OnObjectEndEdit());
|
||||
//--- event was not handled
|
||||
return(CWndObj::OnEvent(id,lparam,dparam,sparam));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CEdit::CEdit(void) : m_read_only(false),
|
||||
m_align_mode(ALIGN_LEFT)
|
||||
{
|
||||
m_color =CONTROLS_EDIT_COLOR;
|
||||
m_color_background=CONTROLS_EDIT_COLOR_BG;
|
||||
m_color_border =CONTROLS_EDIT_COLOR_BORDER;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CEdit::~CEdit(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CEdit::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- call method of the parent class
|
||||
if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create the chart object
|
||||
if(!m_edit.Create(chart,name,subwin,x1,y1,Width(),Height()))
|
||||
return(false);
|
||||
//--- call the settings handler
|
||||
return(OnChange());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameter |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CEdit::ReadOnly(const bool flag)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_read_only=flag;
|
||||
//--- set up the chart object
|
||||
return(m_edit.ReadOnly(flag));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameter |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CEdit::TextAlign(const ENUM_ALIGN_MODE align)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_align_mode=align;
|
||||
//--- set up the chart object
|
||||
return(m_edit.TextAlign(align));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create object on chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CEdit::OnCreate(void)
|
||||
{
|
||||
//--- create the chart object by previously set parameters
|
||||
return(m_edit.Create(m_chart_id,m_name,m_subwin,m_rect.left,m_rect.top,m_rect.Width(),m_rect.Height()));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Display object on chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CEdit::OnShow(void)
|
||||
{
|
||||
return(m_edit.Timeframes(OBJ_ALL_PERIODS));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Hide object from chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CEdit::OnHide(void)
|
||||
{
|
||||
return(m_edit.Timeframes(OBJ_NO_PERIODS));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Absolute movement of the chart object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CEdit::OnMove(void)
|
||||
{
|
||||
//--- position the chart object
|
||||
return(m_edit.X_Distance(m_rect.left) && m_edit.Y_Distance(m_rect.top));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resize the chart object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CEdit::OnResize(void)
|
||||
{
|
||||
//--- resize the chart object
|
||||
return(m_edit.X_Size(m_rect.Width()) && m_edit.Y_Size(m_rect.Height()));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set up the chart object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CEdit::OnChange(void)
|
||||
{
|
||||
//--- set up the chart object
|
||||
return(CWndObj::OnChange() && ReadOnly(m_read_only) && TextAlign(m_align_mode));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "End of editing" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CEdit::OnObjectEndEdit(void)
|
||||
{
|
||||
//--- send the ON_END_EDIT notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_END_EDIT,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "click" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CEdit::OnClick(void)
|
||||
{
|
||||
//--- if editing is enabled, send the ON_START_EDIT notification
|
||||
if(!m_read_only)
|
||||
{
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_START_EDIT,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//--- else send the ON_CLICK notification
|
||||
return(CWnd::OnClick());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,93 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Label.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndObj.mqh"
|
||||
#include <ChartObjects\ChartObjectsTxtControls.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CLabel |
|
||||
//| Usage: control that is displayed by |
|
||||
//| the CChartObjectLabel object |
|
||||
//+------------------------------------------------------------------+
|
||||
class CLabel : public CWndObj
|
||||
{
|
||||
private:
|
||||
CChartObjectLabel m_label; // chart object
|
||||
|
||||
public:
|
||||
CLabel(void);
|
||||
~CLabel(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
|
||||
protected:
|
||||
//--- handlers of object settings
|
||||
virtual bool OnSetText(void) { return(m_label.Description(m_text)); }
|
||||
virtual bool OnSetColor(void) { return(m_label.Color(m_color)); }
|
||||
virtual bool OnSetFont(void) { return(m_label.Font(m_font)); }
|
||||
virtual bool OnSetFontSize(void) { return(m_label.FontSize(m_font_size)); }
|
||||
//--- internal event handlers
|
||||
virtual bool OnCreate(void);
|
||||
virtual bool OnShow(void);
|
||||
virtual bool OnHide(void);
|
||||
virtual bool OnMove(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CLabel::CLabel(void)
|
||||
{
|
||||
m_color=CONTROLS_LABEL_COLOR;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CLabel::~CLabel(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CLabel::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- call method of the parent class
|
||||
if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create the chart object
|
||||
if(!m_label.Create(chart,name,subwin,x1,y1))
|
||||
return(false);
|
||||
//--- call the settings handler
|
||||
return(OnChange());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create object on chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CLabel::OnCreate(void)
|
||||
{
|
||||
//--- create the chart object by previously set parameters
|
||||
return(m_label.Create(m_chart_id,m_name,m_subwin,m_rect.left,m_rect.top));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Display object on chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CLabel::OnShow(void)
|
||||
{
|
||||
return(m_label.Timeframes(OBJ_ALL_PERIODS));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Hide object from chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CLabel::OnHide(void)
|
||||
{
|
||||
return(m_label.Timeframes(OBJ_NO_PERIODS));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Absolute movement of the chart object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CLabel::OnMove(void)
|
||||
{
|
||||
//--- position the chart object
|
||||
return(m_label.X_Distance(m_rect.left) && m_label.Y_Distance(m_rect.top));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,544 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| ListView.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndClient.mqh"
|
||||
#include "Edit.mqh"
|
||||
#include <Arrays\ArrayString.mqh>
|
||||
#include <Arrays\ArrayLong.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CListView |
|
||||
//| Usage: display lists |
|
||||
//+------------------------------------------------------------------+
|
||||
class CListView : public CWndClient
|
||||
{
|
||||
private:
|
||||
//--- dependent controls
|
||||
CEdit m_rows[]; // array of the row objects
|
||||
//--- set up
|
||||
int m_offset; // index of first visible row in array of rows
|
||||
int m_total_view; // number of visible rows
|
||||
int m_item_height; // height of visible row
|
||||
bool m_height_variable; // ïðèçíàê ïåðåìåííîé âûñîòû ñïèñêà
|
||||
//--- data
|
||||
CArrayString m_strings; // array of rows
|
||||
CArrayLong m_values; // array of values
|
||||
int m_current; // index of current row in array of rows
|
||||
|
||||
public:
|
||||
CListView(void);
|
||||
~CListView(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
virtual void Destroy(const int reason=0);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- set up
|
||||
bool TotalView(const int value);
|
||||
//--- fill
|
||||
virtual bool AddItem(const string item,const long value=0);
|
||||
//--- data
|
||||
virtual bool ItemAdd(const string item,const long value=0);
|
||||
virtual bool ItemInsert(const int index,const string item,const long value=0);
|
||||
virtual bool ItemUpdate(const int index,const string item,const long value=0);
|
||||
virtual bool ItemDelete(const int index);
|
||||
virtual bool ItemsClear(void);
|
||||
//--- data
|
||||
int Current(void) { return(m_current); }
|
||||
string Select(void) { return(m_strings.At(m_current)); }
|
||||
bool Select(const int index);
|
||||
bool SelectByText(const string text);
|
||||
bool SelectByValue(const long value);
|
||||
//--- data (read only)
|
||||
long Value(void) { return(m_values.At(m_current)); }
|
||||
//--- state
|
||||
virtual bool Show(void);
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
bool CreateRow(const int index);
|
||||
//--- event handlers
|
||||
virtual bool OnResize(void);
|
||||
//--- handlers of the dependent controls events
|
||||
virtual bool OnVScrollShow(void);
|
||||
virtual bool OnVScrollHide(void);
|
||||
virtual bool OnScrollLineDown(void);
|
||||
virtual bool OnScrollLineUp(void);
|
||||
virtual bool OnItemClick(const int index);
|
||||
//--- redraw
|
||||
bool Redraw(void);
|
||||
bool RowState(const int index,const bool select);
|
||||
bool CheckView(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_BEGIN(CListView)
|
||||
ON_INDEXED_EVENT(ON_CLICK,m_rows,OnItemClick)
|
||||
EVENT_MAP_END(CWndClient)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CListView::CListView(void) : m_offset(0),
|
||||
m_total_view(0),
|
||||
m_item_height(CONTROLS_LIST_ITEM_HEIGHT),
|
||||
m_current(CONTROLS_INVALID_INDEX),
|
||||
m_height_variable(false)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CListView::~CListView(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
int y=y2;
|
||||
//--- if the number of visible rows is previously determined, adjust the vertical size
|
||||
if(!TotalView((y2-y1)/m_item_height))
|
||||
y=m_item_height+y1+2*CONTROLS_BORDER_WIDTH;
|
||||
//--- check the number of visible rows
|
||||
if(m_total_view<1)
|
||||
return(false);
|
||||
//--- call method of the parent class
|
||||
if(!CWndClient::Create(chart,name,subwin,x1,y1,x2,y))
|
||||
return(false);
|
||||
//--- set up
|
||||
if(!m_background.ColorBackground(CONTROLS_LIST_COLOR_BG))
|
||||
return(false);
|
||||
if(!m_background.ColorBorder(CONTROLS_LIST_COLOR_BORDER))
|
||||
return(false);
|
||||
//--- create dependent controls
|
||||
ArrayResize(m_rows,m_total_view);
|
||||
for(int i=0;i<m_total_view;i++)
|
||||
{
|
||||
if(!CreateRow(i))
|
||||
return(false);
|
||||
if(m_height_variable && i>0)
|
||||
m_rows[i].Hide();
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Delete group of controls |
|
||||
//+------------------------------------------------------------------+
|
||||
void CListView::Destroy(const int reason)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
CWndClient::Destroy(reason);
|
||||
//--- clear items
|
||||
m_strings.Clear();
|
||||
m_values.Clear();
|
||||
//---
|
||||
m_offset =0;
|
||||
m_total_view=0;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameter |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::TotalView(const int value)
|
||||
{
|
||||
//--- if parameter is not equal to 0, modifications are not possible
|
||||
if(m_total_view!=0)
|
||||
{
|
||||
m_height_variable=true;
|
||||
return(false);
|
||||
}
|
||||
//--- save value
|
||||
m_total_view=value;
|
||||
//--- parameter has been changed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Makes the control visible |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::Show(void)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
CWndClient::Show();
|
||||
//--- number of items
|
||||
int total=m_strings.Total();
|
||||
//---
|
||||
if(total==0)
|
||||
total=1;
|
||||
//---
|
||||
if(m_height_variable && total<m_total_view)
|
||||
for(int i=total;i<m_total_view;i++)
|
||||
m_rows[i].Hide();
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create "row" |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::CreateRow(const int index)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=CONTROLS_BORDER_WIDTH;
|
||||
int y1=CONTROLS_BORDER_WIDTH+m_item_height*index;
|
||||
int x2=Width()-2*CONTROLS_BORDER_WIDTH;
|
||||
int y2=y1+m_item_height;
|
||||
//--- create
|
||||
if(!m_rows[index].Create(m_chart_id,m_name+"Item"+IntegerToString(index),m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_rows[index].Text(""))
|
||||
return(false);
|
||||
if(!m_rows[index].ReadOnly(true))
|
||||
return(false);
|
||||
if(!RowState(index,false))
|
||||
return(false);
|
||||
if(!Add(m_rows[index]))
|
||||
return(false);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Add item (row) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::AddItem(const string item,const long value)
|
||||
{
|
||||
//--- method left for compatibility with previous version
|
||||
return(ItemAdd(item,value));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Add item (row) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::ItemAdd(const string item,const long value)
|
||||
{
|
||||
//--- add
|
||||
if(!m_strings.Add(item))
|
||||
return(false);
|
||||
if(!m_values.Add((value)?value:m_values.Total()))
|
||||
return(false);
|
||||
//--- number of items
|
||||
int total=m_strings.Total();
|
||||
//--- exit if number of items does not exceed the size of visible area
|
||||
if(total<m_total_view+1)
|
||||
{
|
||||
if(m_height_variable && total!=1)
|
||||
{
|
||||
Height(total*m_item_height+2*CONTROLS_BORDER_WIDTH);
|
||||
if(IS_VISIBLE)
|
||||
m_rows[total-1].Show();
|
||||
}
|
||||
return(Redraw());
|
||||
}
|
||||
//--- if number of items exceeded the size of visible area
|
||||
if(total==m_total_view+1)
|
||||
{
|
||||
//--- enable vertical scrollbar
|
||||
if(!VScrolled(true))
|
||||
return(false);
|
||||
//--- and immediately make it invisible (if needed)
|
||||
if(IS_VISIBLE && !OnVScrollShow())
|
||||
return(false);
|
||||
}
|
||||
//--- set up the scrollbar
|
||||
m_scroll_v.MaxPos(m_strings.Total()-m_total_view);
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Insert item (row) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::ItemInsert(const int index,const string item,const long value)
|
||||
{
|
||||
//--- insert
|
||||
if(!m_strings.Insert(item,index))
|
||||
return(false);
|
||||
if(!m_values.Insert(value,index))
|
||||
return(false);
|
||||
//--- number of items
|
||||
int total=m_strings.Total();
|
||||
//--- exit if number of items does not exceed the size of visible area
|
||||
if(total<m_total_view+1)
|
||||
{
|
||||
if(m_height_variable && total!=1)
|
||||
{
|
||||
Height(total*m_item_height+2*CONTROLS_BORDER_WIDTH);
|
||||
if(IS_VISIBLE)
|
||||
m_rows[total-1].Show();
|
||||
}
|
||||
return(Redraw());
|
||||
}
|
||||
//--- if number of items exceeded the size of visible area
|
||||
if(total==m_total_view+1)
|
||||
{
|
||||
//--- enable vertical scrollbar
|
||||
if(!VScrolled(true))
|
||||
return(false);
|
||||
//--- and immediately make it invisible (if needed)
|
||||
if(IS_VISIBLE && !OnVScrollShow())
|
||||
return(false);
|
||||
}
|
||||
//--- set up the scrollbar
|
||||
m_scroll_v.MaxPos(m_strings.Total()-m_total_view);
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Update item (row) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::ItemUpdate(const int index,const string item,const long value)
|
||||
{
|
||||
//--- update
|
||||
if(!m_strings.Update(index,item))
|
||||
return(false);
|
||||
if(!m_values.Update(index,value))
|
||||
return(false);
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Delete item (row) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::ItemDelete(const int index)
|
||||
{
|
||||
//--- delete
|
||||
if(!m_strings.Delete(index))
|
||||
return(false);
|
||||
if(!m_values.Delete(index))
|
||||
return(false);
|
||||
//--- number of items
|
||||
int total=m_strings.Total();
|
||||
//--- exit if number of items does not exceed the size of visible area
|
||||
if(total<m_total_view)
|
||||
{
|
||||
if(m_height_variable && total!=0)
|
||||
{
|
||||
Height(total*m_item_height+2*CONTROLS_BORDER_WIDTH);
|
||||
m_rows[total].Hide();
|
||||
}
|
||||
return(Redraw());
|
||||
}
|
||||
//--- if number of items exceeded the size of visible area
|
||||
if(total==m_total_view)
|
||||
{
|
||||
//--- disable vertical scrollbar
|
||||
if(!VScrolled(false))
|
||||
return(false);
|
||||
//--- and immediately make it unvisible
|
||||
if(!OnVScrollHide())
|
||||
return(false);
|
||||
}
|
||||
//--- set up the scrollbar
|
||||
m_scroll_v.MaxPos(m_strings.Total()-m_total_view);
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Delete all items |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::ItemsClear(void)
|
||||
{
|
||||
m_offset=0;
|
||||
//--- clear
|
||||
if(!m_strings.Shutdown())
|
||||
return(false);
|
||||
if(!m_values.Shutdown())
|
||||
return(false);
|
||||
//---
|
||||
if(m_height_variable)
|
||||
{
|
||||
Height(m_item_height+2*CONTROLS_BORDER_WIDTH);
|
||||
for(int i=1;i<m_total_view;i++)
|
||||
m_rows[i].Hide();
|
||||
}
|
||||
//--- disable vertical scrollbar
|
||||
if(!VScrolled(false))
|
||||
return(false);
|
||||
//--- and immediately make it unvisible (if needed)
|
||||
if(!OnVScrollHide())
|
||||
return(false);
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Sett current item |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::Select(const int index)
|
||||
{
|
||||
//--- check index
|
||||
if(index>=m_strings.Total())
|
||||
return(false);
|
||||
if(index<0 && index!=CONTROLS_INVALID_INDEX)
|
||||
return(false);
|
||||
//--- unselect
|
||||
if(m_current!=CONTROLS_INVALID_INDEX)
|
||||
RowState(m_current-m_offset,false);
|
||||
//--- select
|
||||
if(index!=CONTROLS_INVALID_INDEX)
|
||||
RowState(index-m_offset,true);
|
||||
//--- save value
|
||||
m_current=index;
|
||||
//--- succeed
|
||||
return(CheckView());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set current item (by text) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::SelectByText(const string text)
|
||||
{
|
||||
//--- find text
|
||||
int index=m_strings.SearchLinear(text);
|
||||
//--- if text is not found, exit without changing the selection
|
||||
if(index==CONTROLS_INVALID_INDEX)
|
||||
return(false);
|
||||
//--- change selection
|
||||
return(Select(index));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set current item (by value) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::SelectByValue(const long value)
|
||||
{
|
||||
//--- find value
|
||||
int index=m_values.SearchLinear(value);
|
||||
//--- if value is not found, exit without changing the selection
|
||||
if(index==CONTROLS_INVALID_INDEX)
|
||||
return(false);
|
||||
//--- change selection
|
||||
return(Select(index));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Redraw |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::Redraw(void)
|
||||
{
|
||||
//--- loop by "rows"
|
||||
for(int i=0;i<m_total_view;i++)
|
||||
{
|
||||
//--- copy text
|
||||
if(!m_rows[i].Text(m_strings.At(i+m_offset)))
|
||||
return(false);
|
||||
//--- select
|
||||
if(!RowState(i,(m_current==i+m_offset)))
|
||||
return(false);
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Change state |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::RowState(const int index,const bool select)
|
||||
{
|
||||
//--- check index
|
||||
if(index<0 || index>=ArraySize(m_rows))
|
||||
return(true);
|
||||
//--- determine colors
|
||||
color text_color=(select) ? CONTROLS_LISTITEM_COLOR_TEXT_SEL : CONTROLS_LISTITEM_COLOR_TEXT;
|
||||
color back_color=(select) ? CONTROLS_LISTITEM_COLOR_BG_SEL : CONTROLS_LISTITEM_COLOR_BG;
|
||||
//--- get pointer
|
||||
CEdit *item=GetPointer(m_rows[index]);
|
||||
//--- recolor the "row"
|
||||
return(item.Color(text_color) && item.ColorBackground(back_color) && item.ColorBorder(back_color));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check visibility of selected row |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::CheckView(void)
|
||||
{
|
||||
//--- check visibility
|
||||
if(m_current>=m_offset && m_current<m_offset+m_total_view)
|
||||
return(true);
|
||||
//--- selected row is not visible
|
||||
int total=m_strings.Total();
|
||||
m_offset=(total-m_current>m_total_view) ? m_current : total-m_total_view;
|
||||
//--- adjust the scrollbar
|
||||
m_scroll_v.CurrPos(m_offset);
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of resizing |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::OnResize(void)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
if(!CWndClient::OnResize())
|
||||
return(false);
|
||||
//--- set up the size of "row"
|
||||
if(VScrolled())
|
||||
OnVScrollShow();
|
||||
else
|
||||
OnVScrollHide();
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Show vertical scrollbar" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::OnVScrollShow(void)
|
||||
{
|
||||
//--- loop by "rows"
|
||||
for(int i=0;i<m_total_view;i++)
|
||||
{
|
||||
//--- resize "rows" according to shown vertical scrollbar
|
||||
m_rows[i].Width(Width()-(CONTROLS_SCROLL_SIZE+CONTROLS_BORDER_WIDTH));
|
||||
}
|
||||
//--- check visibility
|
||||
if(!IS_VISIBLE)
|
||||
{
|
||||
m_scroll_v.Visible(false);
|
||||
return(true);
|
||||
}
|
||||
//--- event is handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Hide vertical scrollbar" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::OnVScrollHide(void)
|
||||
{
|
||||
//--- check visibility
|
||||
if(!IS_VISIBLE)
|
||||
return(true);
|
||||
//--- loop by "rows"
|
||||
for(int i=0;i<m_total_view;i++)
|
||||
{
|
||||
//--- resize "rows" according to hidden vertical scroll bar
|
||||
m_rows[i].Width(Width()-2*CONTROLS_BORDER_WIDTH);
|
||||
}
|
||||
//--- event is handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Scroll up for one row" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::OnScrollLineUp(void)
|
||||
{
|
||||
//--- get new offset
|
||||
m_offset=m_scroll_v.CurrPos();
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Scroll down for one row" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::OnScrollLineDown(void)
|
||||
{
|
||||
//--- get new offset
|
||||
m_offset=m_scroll_v.CurrPos();
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on row |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CListView::OnItemClick(const int index)
|
||||
{
|
||||
//--- select "row"
|
||||
Select(index+m_offset);
|
||||
//--- send notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,124 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Panel.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndObj.mqh"
|
||||
#include <ChartObjects\ChartObjectsTxtControls.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CPanel |
|
||||
//| Usage: control that is displayed by |
|
||||
//| the CChartObjectRectLabel object |
|
||||
//+------------------------------------------------------------------+
|
||||
class CPanel : public CWndObj
|
||||
{
|
||||
private:
|
||||
CChartObjectRectLabel m_rectangle; // chart object
|
||||
//--- parameters of the chart object
|
||||
ENUM_BORDER_TYPE m_border; // border type
|
||||
|
||||
public:
|
||||
CPanel(void);
|
||||
~CPanel(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- parameters of the chart object
|
||||
ENUM_BORDER_TYPE BorderType(void) const { return(m_border); }
|
||||
bool BorderType(const ENUM_BORDER_TYPE type);
|
||||
|
||||
protected:
|
||||
//--- handlers of object settings
|
||||
virtual bool OnSetText(void) { return(m_rectangle.Description(m_text)); }
|
||||
virtual bool OnSetColorBackground(void) { return(m_rectangle.BackColor(m_color_background)); }
|
||||
virtual bool OnSetColorBorder(void) { return(m_rectangle.Color(m_color_border)); }
|
||||
//--- internal event handlers
|
||||
virtual bool OnCreate(void);
|
||||
virtual bool OnShow(void);
|
||||
virtual bool OnHide(void);
|
||||
virtual bool OnMove(void);
|
||||
virtual bool OnResize(void);
|
||||
virtual bool OnChange(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CPanel::CPanel(void) : m_border(BORDER_FLAT)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CPanel::~CPanel(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPanel::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- call method of the parent class
|
||||
if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create the chart object
|
||||
if(!m_rectangle.Create(chart,name,subwin,x1,y1,Width(),Height()))
|
||||
return(false);
|
||||
//--- call the settings handler
|
||||
return(OnChange());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set border type |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPanel::BorderType(const ENUM_BORDER_TYPE type)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_border=type;
|
||||
//--- set up the chart object
|
||||
return(m_rectangle.BorderType(type));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create object on chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPanel::OnCreate(void)
|
||||
{
|
||||
//--- create the chart object by previously set parameters
|
||||
return(m_rectangle.Create(m_chart_id,m_name,m_subwin,m_rect.left,m_rect.top,m_rect.Width(),m_rect.Height()));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Display object on chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPanel::OnShow(void)
|
||||
{
|
||||
return(m_rectangle.Timeframes(OBJ_ALL_PERIODS));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Hide object from chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPanel::OnHide(void)
|
||||
{
|
||||
return(m_rectangle.Timeframes(OBJ_NO_PERIODS));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Absolute movement of the chart object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPanel::OnMove(void)
|
||||
{
|
||||
//--- position the chart object
|
||||
return(m_rectangle.X_Distance(m_rect.left) && m_rectangle.Y_Distance(m_rect.top));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resize the chart object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPanel::OnResize(void)
|
||||
{
|
||||
//--- resize the chart object
|
||||
return(m_rectangle.X_Size(m_rect.Width()) && m_rectangle.Y_Size(m_rect.Height()));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set up the chart object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPanel::OnChange(void)
|
||||
{
|
||||
//--- set up the chart object
|
||||
return(CWndObj::OnChange() && m_rectangle.BorderType(m_border));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,125 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Picture.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndObj.mqh"
|
||||
#include <ChartObjects\ChartObjectsBmpControls.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CPicture |
|
||||
//| Note: image displayed by |
|
||||
//| the CChartObjectBmpLabel object |
|
||||
//+------------------------------------------------------------------+
|
||||
class CPicture : public CWndObj
|
||||
{
|
||||
private:
|
||||
CChartObjectBmpLabel m_picture; // chart object
|
||||
//--- parameters of the chart object
|
||||
int m_border; // border width
|
||||
string m_bmp_name; // filename
|
||||
|
||||
public:
|
||||
CPicture(void);
|
||||
~CPicture(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- parameters of the chart object
|
||||
int Border(void) const { return(m_border); }
|
||||
bool Border(const int value);
|
||||
string BmpName(void) const { return(m_bmp_name); }
|
||||
bool BmpName(const string name);
|
||||
|
||||
protected:
|
||||
//--- internal event handlers
|
||||
virtual bool OnCreate(void);
|
||||
virtual bool OnShow(void);
|
||||
virtual bool OnHide(void);
|
||||
virtual bool OnMove(void);
|
||||
virtual bool OnChange(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CPicture::CPicture(void) : m_border(0),
|
||||
m_bmp_name(NULL)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CPicture::~CPicture(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPicture::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- call method of the parent class
|
||||
if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create the chart object
|
||||
if(!m_picture.Create(chart,name,subwin,x1,y1))
|
||||
return(false);
|
||||
//--- call the settings handler
|
||||
return(OnChange());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set border width |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPicture::Border(const int value)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_border=value;
|
||||
//--- set up the chart object
|
||||
return(m_picture.Width(value));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set image |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPicture::BmpName(const string name)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_bmp_name=name;
|
||||
//--- set up the chart object
|
||||
return(m_picture.BmpFileOn(name));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create object on chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPicture::OnCreate(void)
|
||||
{
|
||||
//--- create the chart object by previously set parameters
|
||||
return(m_picture.Create(m_chart_id,m_name,m_subwin,m_rect.left,m_rect.top));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Display object on chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPicture::OnShow(void)
|
||||
{
|
||||
return(m_picture.Timeframes(OBJ_ALL_PERIODS));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Hide object from chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPicture::OnHide(void)
|
||||
{
|
||||
return(m_picture.Timeframes(OBJ_NO_PERIODS));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Absolute movement of the chart object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPicture::OnMove(void)
|
||||
{
|
||||
//--- position the chart object
|
||||
return(m_picture.X_Distance(m_rect.left) && m_picture.Y_Distance(m_rect.top));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set up the chart object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPicture::OnChange(void)
|
||||
{
|
||||
//--- set up the chart object
|
||||
return(m_picture.Width(m_border) && m_picture.BmpFileOn(m_bmp_name));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,160 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| RadioButton.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndContainer.mqh"
|
||||
#include "BmpButton.mqh"
|
||||
#include "Edit.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resources |
|
||||
//+------------------------------------------------------------------+
|
||||
#resource "res\\RadioButtonOn.bmp"
|
||||
#resource "res\\RadioButtonOff.bmp"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CRadioButton |
|
||||
//| Usage: class that implements the "RadioButton" control |
|
||||
//+------------------------------------------------------------------+
|
||||
class CRadioButton : public CWndContainer
|
||||
{
|
||||
private:
|
||||
//--- dependent controls
|
||||
CBmpButton m_button; // button object
|
||||
CEdit m_label; // label object
|
||||
|
||||
public:
|
||||
CRadioButton(void);
|
||||
~CRadioButton(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- settings
|
||||
string Text(void) const { return(m_label.Text()); }
|
||||
bool Text(const string value) { return(m_label.Text(value)); }
|
||||
color Color(void) const { return(m_label.Color()); }
|
||||
bool Color(const color value) { return(m_label.Color(value)); }
|
||||
//--- state
|
||||
bool State(void) const { return(m_button.Pressed()); }
|
||||
bool State(const bool flag) { return(m_button.Pressed(flag)); }
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
virtual bool CreateButton(void);
|
||||
virtual bool CreateLabel(void);
|
||||
//--- handlers of the dependent controls events
|
||||
virtual bool OnClickButton(void);
|
||||
virtual bool OnClickLabel(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_BEGIN(CRadioButton)
|
||||
ON_EVENT(ON_CLICK,m_button,OnClickButton)
|
||||
ON_EVENT(ON_CLICK,m_label,OnClickLabel)
|
||||
EVENT_MAP_END(CWndContainer)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CRadioButton::CRadioButton(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CRadioButton::~CRadioButton(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioButton::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- call method of the parent class
|
||||
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create dependent controls
|
||||
if(!CreateButton())
|
||||
return(false);
|
||||
if(!CreateLabel())
|
||||
return(false);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioButton::CreateButton(void)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=CONTROLS_RADIO_BUTTON_X_OFF;
|
||||
int y1=CONTROLS_RADIO_BUTTON_Y_OFF;
|
||||
int x2=x1+CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_BUTTON_SIZE-CONTROLS_BORDER_WIDTH;
|
||||
//--- create
|
||||
if(!m_button.Create(m_chart_id,m_name+"Button",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_button.BmpNames("::res\\RadioButtonOff.bmp","::res\\RadioButtonOn.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_button))
|
||||
return(false);
|
||||
m_button.Locking(true);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create label |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioButton::CreateLabel(void)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=CONTROLS_RADIO_LABEL_X_OFF;
|
||||
int y1=CONTROLS_RADIO_LABEL_Y_OFF;
|
||||
int x2=Width();
|
||||
int y2=Height();
|
||||
//--- create
|
||||
if(!m_label.Create(m_chart_id,m_name+"Label",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_label.Text(m_name))
|
||||
return(false);
|
||||
if(!Add(m_label))
|
||||
return(false);
|
||||
m_label.ReadOnly(true);
|
||||
m_label.ColorBackground(CONTROLS_CHECKGROUP_COLOR_BG);
|
||||
m_label.ColorBorder(CONTROLS_CHECKGROUP_COLOR_BG);
|
||||
//--- succeeded
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioButton::OnClickButton(void)
|
||||
{
|
||||
//--- if button is in the "turned off" state, turn it on again and complete the handling
|
||||
//--- this is due to that radio button can not be turned off by clicking on it (it can be only turned on)
|
||||
if(!m_button.Pressed())
|
||||
{
|
||||
//--- turn on the radio button
|
||||
if(!m_button.Pressed(true))
|
||||
return(false);
|
||||
}
|
||||
//--- send the "changed state" event
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on label |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioButton::OnClickLabel(void)
|
||||
{
|
||||
//--- if button is in the "turned on" state, simply complete the handling
|
||||
//--- this is due to that radio button can not be turned off by clicking on it (it can be only turned on)
|
||||
if(m_button.Pressed())
|
||||
return(true);
|
||||
//--- turn on the radio button
|
||||
m_button.Pressed(true);
|
||||
//--- return the result of the button click handler
|
||||
return(OnClickButton());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,361 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| RadioGroup.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndClient.mqh"
|
||||
#include "RadioButton.mqh"
|
||||
#include <Arrays\ArrayString.mqh>
|
||||
#include <Arrays\ArrayLong.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CRadioGroup |
|
||||
//| Usage: view and edit radio buttons |
|
||||
//+------------------------------------------------------------------+
|
||||
class CRadioGroup : public CWndClient
|
||||
{
|
||||
private:
|
||||
//--- dependent controls
|
||||
CRadioButton m_rows[]; // array of the row objects
|
||||
//--- set up
|
||||
int m_offset; // index of first visible row in array of rows
|
||||
int m_total_view; // number of visible rows
|
||||
int m_item_height; // height of visible row
|
||||
//--- data
|
||||
CArrayString m_strings; // array of rows
|
||||
CArrayLong m_values; // array of values
|
||||
int m_current; // index of current row in array of rows
|
||||
|
||||
public:
|
||||
CRadioGroup(void);
|
||||
~CRadioGroup(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
virtual void Destroy(const int reason=0);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- fill
|
||||
virtual bool AddItem(const string item,const long value=0);
|
||||
//--- data
|
||||
long Value(void) const { return(m_values.At(m_current)); }
|
||||
bool Value(const long value);
|
||||
bool ValueCheck(long value) const;
|
||||
//--- state
|
||||
virtual bool Show(void);
|
||||
//--- methods for working with files
|
||||
virtual bool Save(const int file_handle);
|
||||
virtual bool Load(const int file_handle);
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
bool CreateButton(const int index);
|
||||
//--- handlers of the dependent controls events
|
||||
virtual bool OnVScrollShow(void);
|
||||
virtual bool OnVScrollHide(void);
|
||||
virtual bool OnScrollLineDown(void);
|
||||
virtual bool OnScrollLineUp(void);
|
||||
virtual bool OnChangeItem(const int row_index);
|
||||
//--- redraw
|
||||
bool Redraw(void);
|
||||
bool RowState(const int index,const bool select);
|
||||
void Select(const int index);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_BEGIN(CRadioGroup)
|
||||
ON_INDEXED_EVENT(ON_CHANGE,m_rows,OnChangeItem)
|
||||
EVENT_MAP_END(CWndClient)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CRadioGroup::CRadioGroup(void) : m_offset(0),
|
||||
m_total_view(0),
|
||||
m_item_height(CONTROLS_LIST_ITEM_HEIGHT),
|
||||
m_current(CONTROLS_INVALID_INDEX)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CRadioGroup::~CRadioGroup(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- determine the number of visible rows
|
||||
m_total_view=(y2-y1)/m_item_height;
|
||||
//--- check the number of visible rows
|
||||
if(m_total_view<1)
|
||||
return(false);
|
||||
//--- call method of the parent class
|
||||
if(!CWndClient::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- set up
|
||||
if(!m_background.ColorBackground(CONTROLS_RADIOGROUP_COLOR_BG))
|
||||
return(false);
|
||||
if(!m_background.ColorBorder(CONTROLS_RADIOGROUP_COLOR_BORDER))
|
||||
return(false);
|
||||
//--- create dependent controls
|
||||
ArrayResize(m_rows,m_total_view);
|
||||
for(int i=0;i<m_total_view;i++)
|
||||
if(!CreateButton(i))
|
||||
return(false);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Delete group of controls |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRadioGroup::Destroy(const int reason)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
CWndClient::Destroy(reason);
|
||||
//--- clear items
|
||||
m_strings.Clear();
|
||||
m_values.Clear();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create "row" |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::CreateButton(const int index)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=CONTROLS_BORDER_WIDTH;
|
||||
int y1=CONTROLS_BORDER_WIDTH+m_item_height*index;
|
||||
int x2=Width()-CONTROLS_BORDER_WIDTH;
|
||||
int y2=y1+m_item_height;
|
||||
//--- create
|
||||
if(!m_rows[index].Create(m_chart_id,m_name+"Item"+IntegerToString(index),m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_rows[index].Text(""))
|
||||
return(false);
|
||||
if(!Add(m_rows[index]))
|
||||
return(false);
|
||||
m_rows[index].Hide();
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Add item (row) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::AddItem(const string item,const long value)
|
||||
{
|
||||
//--- check value
|
||||
if(value!=0 && !ValueCheck(value))
|
||||
return(false);
|
||||
//--- add
|
||||
if(!m_strings.Add(item))
|
||||
return(false);
|
||||
if(!m_values.Add(value))
|
||||
return(false);
|
||||
//--- number of items
|
||||
int total=m_strings.Total();
|
||||
//--- exit if number of items does not exceed the size of visible area
|
||||
if(total<m_total_view+1)
|
||||
{
|
||||
if(IS_VISIBLE && total!=0)
|
||||
m_rows[total-1].Show();
|
||||
return(Redraw());
|
||||
}
|
||||
//--- if number of items exceeded the size of visible area
|
||||
if(total==m_total_view+1)
|
||||
{
|
||||
//--- enable vertical scrollbar
|
||||
if(!VScrolled(true))
|
||||
return(false);
|
||||
//--- and immediately make it invisible (if needed)
|
||||
if(!IS_VISIBLE)
|
||||
m_scroll_v.Visible(false);
|
||||
|
||||
}
|
||||
//--- set up the scrollbar
|
||||
m_scroll_v.MaxPos(m_strings.Total()-m_total_view);
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::Value(const long value)
|
||||
{
|
||||
//--- çíà÷åíèå äîëæíî ïðèñóòñòâîâàòü â íàáîðå
|
||||
int total=m_values.Total();
|
||||
//---
|
||||
for(int i=0;i<total;i++)
|
||||
if(m_values.At(i)==value)
|
||||
Select(i+m_offset);
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::ValueCheck(long value) const
|
||||
{
|
||||
//--- ïðîâåðÿåìîå çíà÷åíèå íå äîëæíî äóáëèðîâàòü óæå ñóùåñòâóþùåå
|
||||
int total=m_values.Total();
|
||||
//---
|
||||
for(int i=0;i<total;i++)
|
||||
if(m_values.At(i)==value)
|
||||
return(false);
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Makes the group visible |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::Show(void)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
if(!CWndClient::Show())
|
||||
return(false);
|
||||
//--- loop by rows
|
||||
int total=m_values.Total();
|
||||
for(int i=total;i<m_total_view;i++)
|
||||
m_rows[i].Hide();
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::Save(const int file_handle)
|
||||
{
|
||||
//--- check
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//---
|
||||
FileWriteLong(file_handle,Value());
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::Load(const int file_handle)
|
||||
{
|
||||
//--- check
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//---
|
||||
if(!FileIsEnding(file_handle))
|
||||
Value(FileReadLong(file_handle));
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Sett current item |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRadioGroup::Select(const int index)
|
||||
{
|
||||
//--- disable the "ON" state
|
||||
if(m_current!=-1)
|
||||
RowState(m_current-m_offset,false);
|
||||
//--- enable the "ON" state
|
||||
if(index!=-1)
|
||||
RowState(index-m_offset,true);
|
||||
//--- save value
|
||||
m_current=index;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Redraw |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::Redraw(void)
|
||||
{
|
||||
//--- loop by "rows"
|
||||
for(int i=0;i<m_total_view;i++)
|
||||
{
|
||||
//--- copy text
|
||||
if(!m_rows[i].Text(m_strings.At(i+m_offset)))
|
||||
return(false);
|
||||
//--- select
|
||||
if(!RowState(i,(m_current==i+m_offset)))
|
||||
return(false);
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Change state |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::RowState(const int index,const bool select)
|
||||
{
|
||||
//--- check index
|
||||
if(index<0 || index>=ArraySize(m_rows))
|
||||
return(true);
|
||||
//--- change state
|
||||
return(m_rows[index].State(select));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Show vertical scrollbar" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::OnVScrollShow(void)
|
||||
{
|
||||
//--- loop by "rows"
|
||||
for(int i=0;i<m_total_view;i++)
|
||||
{
|
||||
//--- resize "rows" according to shown vertical scrollbar
|
||||
m_rows[i].Width(Width()-(CONTROLS_SCROLL_SIZE+CONTROLS_BORDER_WIDTH));
|
||||
}
|
||||
//--- check visibility
|
||||
if(!IS_VISIBLE)
|
||||
{
|
||||
m_scroll_v.Visible(false);
|
||||
return(true);
|
||||
}
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Hide vertical scrollbar" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::OnVScrollHide(void)
|
||||
{
|
||||
//--- check visibility
|
||||
if(!IS_VISIBLE)
|
||||
return(true);
|
||||
//--- loop by "rows"
|
||||
for(int i=0;i<m_total_view;i++)
|
||||
{
|
||||
//--- resize "rows" according to hidden vertical scroll bar
|
||||
m_rows[i].Width(Width()-CONTROLS_BORDER_WIDTH);
|
||||
}
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Scroll up for one row" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::OnScrollLineUp(void)
|
||||
{
|
||||
//--- get new offset
|
||||
m_offset=m_scroll_v.CurrPos();
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Scroll down for one row" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::OnScrollLineDown(void)
|
||||
{
|
||||
//--- get new offset
|
||||
m_offset=m_scroll_v.CurrPos();
|
||||
//--- redraw
|
||||
return(Redraw());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of changing a "row" state |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRadioGroup::OnChangeItem(const int row_index)
|
||||
{
|
||||
//--- select "row"
|
||||
Select(row_index+m_offset);
|
||||
//--- send notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,279 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Rect.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
//| Structure CPoint |
|
||||
//| Usage: point of chart in Cartesian coordinates |
|
||||
//+------------------------------------------------------------------+
|
||||
struct CPoint
|
||||
{
|
||||
int x; // horizontal coordinate
|
||||
int y; // vertical coordinate
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Structure CSize |
|
||||
//| Usage: size of area of chart in Cartesian coordinates |
|
||||
//+------------------------------------------------------------------+
|
||||
struct CSize
|
||||
{
|
||||
int cx; // horizontal size
|
||||
int cy; // vertical size
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Structure CRect |
|
||||
//| Usage: area of chart in Cartesian coordinates |
|
||||
//+------------------------------------------------------------------+
|
||||
struct CRect
|
||||
{
|
||||
int left; // left coordinate
|
||||
int top; // top coordinate
|
||||
int right; // right coordinate
|
||||
int bottom; // bottom coordinate
|
||||
|
||||
//--- methods
|
||||
CPoint LeftTop(void) const;
|
||||
void LeftTop(const int x,const int y);
|
||||
void LeftTop(const CPoint& point);
|
||||
CPoint RightBottom(void) const;
|
||||
void RightBottom(const int x,const int y);
|
||||
void RightBottom(const CPoint& point);
|
||||
CPoint CenterPoint(void) const;
|
||||
int Width(void) const { return(right-left); }
|
||||
void Width(const int w) { right=left+w; }
|
||||
int Height(void) const { return(bottom-top); }
|
||||
void Height(const int h) { bottom=top+h; }
|
||||
CSize Size(void) const;
|
||||
void Size(const int cx,const int cy);
|
||||
void Size(const CSize& size);
|
||||
void SetBound(const int l,const int t,const int r,const int b);
|
||||
void SetBound(const CRect& rect);
|
||||
void SetBound(const CPoint& point,const CSize& size);
|
||||
void SetBound(const CPoint& left_top,const CPoint& right_bottom);
|
||||
void Move(const int x,const int y);
|
||||
void Move(const CPoint& point);
|
||||
void Shift(const int dx,const int dy);
|
||||
void Shift(const CPoint& point);
|
||||
void Shift(const CSize& size);
|
||||
bool Contains(const int x,const int y) const;
|
||||
bool Contains(const CPoint& point) const;
|
||||
void Normalize(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
CPoint CRect::LeftTop(void) const
|
||||
{
|
||||
CPoint point;
|
||||
//--- action
|
||||
point.x=left;
|
||||
point.y=top;
|
||||
//--- result
|
||||
return(point);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::LeftTop(const int x,const int y)
|
||||
{
|
||||
left=x;
|
||||
top =y;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::LeftTop(const CPoint& point)
|
||||
{
|
||||
left=point.x;
|
||||
top =point.y;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
CPoint CRect::RightBottom(void) const
|
||||
{
|
||||
CPoint point;
|
||||
//--- action
|
||||
point.x=right;
|
||||
point.y=bottom;
|
||||
//--- result
|
||||
return(point);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::RightBottom(const int x,const int y)
|
||||
{
|
||||
right =x;
|
||||
bottom=y;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::RightBottom(const CPoint& point)
|
||||
{
|
||||
right =point.x;
|
||||
bottom=point.y;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
CPoint CRect::CenterPoint(void) const
|
||||
{
|
||||
CPoint point;
|
||||
//--- action
|
||||
point.x=left+Width()/2;
|
||||
point.y=top+Height()/2;
|
||||
//--- result
|
||||
return(point);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
CSize CRect::Size(void) const
|
||||
{
|
||||
CSize size;
|
||||
//--- action
|
||||
size.cx=right-left;
|
||||
size.cy=bottom-top;
|
||||
//--- result
|
||||
return(size);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::Size(const int cx,const int cy)
|
||||
{
|
||||
right =left+cx;
|
||||
bottom=top+cy;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::Size(const CSize& size)
|
||||
{
|
||||
right =left+size.cx;
|
||||
bottom=top+size.cy;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::SetBound(const int l,const int t,const int r,const int b)
|
||||
{
|
||||
left =l;
|
||||
top =t;
|
||||
right =r;
|
||||
bottom=b;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::SetBound(const CRect& rect)
|
||||
{
|
||||
left =rect.left;
|
||||
top =rect.top;
|
||||
right =rect.right;
|
||||
bottom=rect.bottom;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::SetBound(const CPoint& point,const CSize& size)
|
||||
{
|
||||
LeftTop(point);
|
||||
Size(size);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameters of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::SetBound(const CPoint& left_top,const CPoint& right_bottom)
|
||||
{
|
||||
LeftTop(left_top);
|
||||
RightBottom(right_bottom);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Absolute movement of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::Move(const int x,const int y)
|
||||
{
|
||||
right +=x-left;
|
||||
bottom+=y-top;
|
||||
left =x;
|
||||
top =y;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Absolute movement of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::Move(const CPoint& point)
|
||||
{
|
||||
right +=point.x-left;
|
||||
bottom+=point.y-top;
|
||||
left =point.x;
|
||||
top =point.y;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Relative movement of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::Shift(const int dx,const int dy)
|
||||
{
|
||||
left +=dx;
|
||||
top +=dy;
|
||||
right +=dx;
|
||||
bottom+=dy;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Relative movement of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::Shift(const CPoint& point)
|
||||
{
|
||||
left +=point.x;
|
||||
top +=point.y;
|
||||
right +=point.x;
|
||||
bottom+=point.y;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Relative movement of area |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::Shift(const CSize& size)
|
||||
{
|
||||
left +=size.cx;
|
||||
top +=size.cy;
|
||||
right +=size.cx;
|
||||
bottom+=size.cy;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check if a point is within the area |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRect::Contains(const int x,const int y) const
|
||||
{
|
||||
//--- check and return the result
|
||||
return(x>=left && x<=right && y>=top && y<=bottom);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check if a point is within the area |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CRect::Contains(const CPoint& point) const
|
||||
{
|
||||
//--- check and return the result
|
||||
return(point.x>=left && point.x<=right && point.y>=top && point.y<=bottom);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Standardizes the height and width |
|
||||
//+------------------------------------------------------------------+
|
||||
void CRect::Normalize(void)
|
||||
{
|
||||
if(left>right)
|
||||
{
|
||||
int tmp1=left;
|
||||
left=right;
|
||||
right=tmp1;
|
||||
}
|
||||
if(top>bottom)
|
||||
{
|
||||
int tmp2=top;
|
||||
top=bottom;
|
||||
bottom=tmp2;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,675 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Scrolls.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndContainer.mqh"
|
||||
#include "Panel.mqh"
|
||||
#include "BmpButton.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resources |
|
||||
//+------------------------------------------------------------------+
|
||||
#resource "res\\Up.bmp"
|
||||
#resource "res\\ThumbVert.bmp"
|
||||
#resource "res\\Down.bmp"
|
||||
#resource "res\\Left.bmp"
|
||||
#resource "res\\ThumbHor.bmp"
|
||||
#resource "res\\Right.bmp"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CScroll |
|
||||
//| Usage: base class for scrollbars |
|
||||
//+------------------------------------------------------------------+
|
||||
class CScroll : public CWndContainer
|
||||
{
|
||||
protected:
|
||||
//--- dependent controls
|
||||
CPanel m_back; // the "scrollbar background" object
|
||||
CBmpButton m_inc; // the "increment button" object ("down" for vertical scrollbar, "right" for horizontal scrollbar)
|
||||
CBmpButton m_dec; // the "decrement button" object ("up" for vertical scrollbar, "left" for horizontal scrollbar)
|
||||
CBmpButton m_thumb; // the "scroll box" object
|
||||
//--- set up
|
||||
int m_min_pos; // minimum value
|
||||
int m_max_pos; // maximum value
|
||||
//--- state
|
||||
int m_curr_pos; // current value
|
||||
|
||||
public:
|
||||
CScroll(void);
|
||||
~CScroll(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- set up
|
||||
int MinPos(void) const { return(m_min_pos); }
|
||||
void MinPos(const int value);
|
||||
int MaxPos(void) const { return(m_max_pos); }
|
||||
void MaxPos(const int value);
|
||||
//--- state
|
||||
int CurrPos(void) const { return(m_curr_pos); }
|
||||
bool CurrPos(int value);
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
virtual bool CreateBack(void);
|
||||
virtual bool CreateInc(void) { return(true); }
|
||||
virtual bool CreateDec(void) { return(true); }
|
||||
virtual bool CreateThumb(void) { return(true); }
|
||||
//--- handlers of the dependent controls events
|
||||
virtual bool OnClickInc(void);
|
||||
virtual bool OnClickDec(void);
|
||||
//--- internal event handlers
|
||||
virtual bool OnShow(void);
|
||||
virtual bool OnHide(void);
|
||||
virtual bool OnChangePos(void) { return(true); }
|
||||
//--- handlers of dragging
|
||||
virtual bool OnThumbDragStart(void) { return(true); }
|
||||
virtual bool OnThumbDragProcess(void) { return(true); }
|
||||
virtual bool OnThumbDragEnd(void) { return(true); }
|
||||
//--- calculate position by coordinate
|
||||
virtual int CalcPos(const int coord) { return(0); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_BEGIN(CScroll)
|
||||
ON_EVENT(ON_CLICK,m_inc,OnClickInc)
|
||||
ON_EVENT(ON_CLICK,m_dec,OnClickDec)
|
||||
ON_EVENT(ON_DRAG_START,m_thumb,OnThumbDragStart)
|
||||
ON_EVENT_PTR(ON_DRAG_PROCESS,m_drag_object,OnThumbDragProcess)
|
||||
ON_EVENT_PTR(ON_DRAG_END,m_drag_object,OnThumbDragEnd)
|
||||
EVENT_MAP_END(CWndContainer)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CScroll::CScroll(void) : m_curr_pos(0),
|
||||
m_min_pos(0),
|
||||
m_max_pos(0)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CScroll::~CScroll(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScroll::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- call method of the parent class
|
||||
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create dependent controls
|
||||
if(!CreateBack())
|
||||
return(false);
|
||||
if(!CreateInc())
|
||||
return(false);
|
||||
if(!CreateDec())
|
||||
return(false);
|
||||
if(!CreateThumb())
|
||||
return(false);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create scrollbar background |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScroll::CreateBack(void)
|
||||
{
|
||||
//--- create
|
||||
if(!m_back.Create(m_chart_id,m_name+"Back",m_subwin,0,0,Width(),Height()))
|
||||
return(false);
|
||||
if(!m_back.ColorBackground(CONTROLS_SCROLL_COLOR_BG))
|
||||
return(false);
|
||||
if(!m_back.ColorBorder(CONTROLS_SCROLL_COLOR_BORDER))
|
||||
return(false);
|
||||
if(!Add(m_back))
|
||||
return(false);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set current value |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScroll::CurrPos(int value)
|
||||
{
|
||||
//--- check value
|
||||
if(value<m_min_pos)
|
||||
value=m_min_pos;
|
||||
if(value>m_max_pos)
|
||||
value=m_max_pos;
|
||||
//--- if value was changed
|
||||
if(m_curr_pos!=value)
|
||||
{
|
||||
m_curr_pos=value;
|
||||
//--- call virtual handler
|
||||
return(OnChangePos());
|
||||
}
|
||||
//--- value has not been changed
|
||||
return(false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set minimum value |
|
||||
//+------------------------------------------------------------------+
|
||||
void CScroll::MinPos(const int value)
|
||||
{
|
||||
//--- if value was changed
|
||||
if(m_min_pos!=value)
|
||||
{
|
||||
m_min_pos=value;
|
||||
//--- adjust the scroll box position
|
||||
CurrPos(m_curr_pos);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set maximum value |
|
||||
//+------------------------------------------------------------------+
|
||||
void CScroll::MaxPos(const int value)
|
||||
{
|
||||
//--- if value was changed
|
||||
if(m_max_pos!=value)
|
||||
{
|
||||
m_max_pos=value;
|
||||
//--- adjust the scroll box position
|
||||
CurrPos(m_curr_pos);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Show scrollbar" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScroll::OnShow(void)
|
||||
{
|
||||
if(m_id==CONTROLS_INVALID_ID)
|
||||
return(true);
|
||||
//--- send notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_SHOW,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Hide scrollbar" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScroll::OnHide(void)
|
||||
{
|
||||
if(m_id==CONTROLS_INVALID_ID)
|
||||
return(true);
|
||||
//--- send notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_HIDE,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on the "increment" button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScroll::OnClickInc(void)
|
||||
{
|
||||
//--- try to increment current value
|
||||
if(!CurrPos(m_curr_pos+1))
|
||||
return(true);
|
||||
//--- if value was changed, send notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_SCROLL_INC,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on the "decrement" button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScroll::OnClickDec(void)
|
||||
{
|
||||
//--- try to decrement current value
|
||||
if(!CurrPos(m_curr_pos-1))
|
||||
return(true);
|
||||
//--- if value was changed, send notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_SCROLL_DEC,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CScrollV |
|
||||
//| Usage: class of vertical scrollbar |
|
||||
//+------------------------------------------------------------------+
|
||||
class CScrollV : public CScroll
|
||||
{
|
||||
public:
|
||||
CScrollV(void);
|
||||
~CScrollV(void);
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
virtual bool CreateInc(void);
|
||||
virtual bool CreateDec(void);
|
||||
virtual bool CreateThumb(void);
|
||||
//--- internal event handlers
|
||||
virtual bool OnResize(void);
|
||||
virtual bool OnChangePos(void);
|
||||
//--- handlers of dragging
|
||||
virtual bool OnThumbDragStart(void);
|
||||
virtual bool OnThumbDragProcess(void);
|
||||
virtual bool OnThumbDragEnd(void);
|
||||
//--- calculate position by coordinate
|
||||
virtual int CalcPos(const int coord);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CScrollV::CScrollV(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CScrollV::~CScrollV(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create the "Increment" button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollV::CreateInc(void)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=CONTROLS_BORDER_WIDTH;
|
||||
int y1=Height()-CONTROLS_SCROLL_SIZE+CONTROLS_BORDER_WIDTH;
|
||||
int x2=x1+CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_BUTTON_SIZE;
|
||||
//--- create
|
||||
if(!m_inc.Create(m_chart_id,m_name+"Inc",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_inc.BmpNames("::res\\Down.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_inc))
|
||||
return(false);
|
||||
//--- property
|
||||
m_inc.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create the "Decrement" button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollV::CreateDec(void)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=CONTROLS_BORDER_WIDTH;
|
||||
int y1=CONTROLS_BORDER_WIDTH;
|
||||
int x2=x1+CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_BUTTON_SIZE;
|
||||
//--- create
|
||||
if(!m_dec.Create(m_chart_id,m_name+"Dec",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_dec.BmpNames("::res\\Up.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_dec))
|
||||
return(false);
|
||||
//--- property
|
||||
m_dec.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create scroll box |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollV::CreateThumb(void)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=CONTROLS_BORDER_WIDTH;
|
||||
int y1=CONTROLS_SCROLL_SIZE-CONTROLS_BORDER_WIDTH;
|
||||
int x2=x1+CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_SCROLL_THUMB_SIZE;
|
||||
//--- create
|
||||
if(!m_thumb.Create(m_chart_id,m_name+"Thumb",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_thumb.BmpNames("::res\\ThumbVert.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_thumb))
|
||||
return(false);
|
||||
m_thumb.PropFlags(WND_PROP_FLAG_CAN_DRAG);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of changing current state |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollV::OnChangePos(void)
|
||||
{
|
||||
//--- check if scrolling is possible
|
||||
if(m_max_pos-m_min_pos<=0)
|
||||
return(Visible(false));
|
||||
else
|
||||
if(!Visible(true))
|
||||
return(false);
|
||||
//--- calculate new coordinated of the scrollbar
|
||||
int steps =m_max_pos-m_min_pos; // number of steps to change position
|
||||
int min_coord=m_dec.Bottom(); // minimum possible coordinate (corresponds to the m_min_pos value)
|
||||
int max_coord=m_inc.Top()-m_thumb.Height(); // maximum possible coordinate (corresponds to the m_max_pos value)
|
||||
int new_coord=min_coord+(max_coord-min_coord)*m_curr_pos/steps; // new coordinate
|
||||
//--- adjust the scroll box position
|
||||
return(m_thumb.Move(m_thumb.Left(),new_coord));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of resizing |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollV::OnResize(void)
|
||||
{
|
||||
//--- can not change the lateral size
|
||||
if(Width()!=CONTROLS_SCROLL_SIZE)
|
||||
m_rect.Width(CONTROLS_SCROLL_SIZE);
|
||||
//--- resize the scrollbar background
|
||||
if(!m_back.Size(Size()))
|
||||
return(false);
|
||||
//--- move the "Increment" button
|
||||
if(!m_inc.Move(m_inc.Left(),Bottom()-CONTROLS_SCROLL_SIZE))
|
||||
return(false);
|
||||
//--- adjust the scroll box position
|
||||
return(OnChangePos());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Start dragging the "slider" |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollV::OnThumbDragStart(void)
|
||||
{
|
||||
if(m_drag_object==NULL)
|
||||
{
|
||||
m_drag_object=new CDragWnd;
|
||||
if(m_drag_object==NULL)
|
||||
return(false);
|
||||
}
|
||||
//--- calculate coordinates
|
||||
int x1=m_thumb.Left()-CONTROLS_DRAG_SPACING;
|
||||
int y1=m_thumb.Top()-CONTROLS_DRAG_SPACING;
|
||||
int x2=m_thumb.Right()+CONTROLS_DRAG_SPACING;
|
||||
int y2=m_thumb.Bottom()+CONTROLS_DRAG_SPACING;
|
||||
//--- create
|
||||
m_drag_object.Create(m_chart_id,"",m_subwin,x1,y1,x2,y2);
|
||||
m_drag_object.PropFlags(WND_PROP_FLAG_CAN_DRAG);
|
||||
//--- îãðàíè÷åíèÿ
|
||||
m_drag_object.Limits(x1,m_dec.Bottom()-CONTROLS_DRAG_SPACING,x2,m_inc.Top()+CONTROLS_DRAG_SPACING);
|
||||
//--- set mouse params
|
||||
m_drag_object.MouseX(m_thumb.MouseX());
|
||||
m_drag_object.MouseY(m_thumb.MouseY());
|
||||
m_drag_object.MouseFlags(m_thumb.MouseFlags());
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Continue dragging the "slider" |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollV::OnThumbDragProcess(void)
|
||||
{
|
||||
//--- checking
|
||||
if(m_drag_object==NULL)
|
||||
return(false);
|
||||
//--- calculate coordinates
|
||||
int x=m_drag_object.Left()+CONTROLS_DRAG_SPACING;
|
||||
int y=m_drag_object.Top()+CONTROLS_DRAG_SPACING;
|
||||
//--- calculate new position
|
||||
int new_pos=CalcPos(y);
|
||||
if(new_pos!=m_curr_pos)
|
||||
{
|
||||
ushort event_id=(m_curr_pos<new_pos) ? ON_SCROLL_INC : ON_SCROLL_DEC;
|
||||
m_curr_pos=new_pos;
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,event_id,m_id,0.0,m_name);
|
||||
}
|
||||
//--- move thumb
|
||||
m_thumb.Move(x,y);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| End dragging the "slider" |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollV::OnThumbDragEnd(void)
|
||||
{
|
||||
if(m_drag_object!=NULL)
|
||||
{
|
||||
m_thumb.MouseFlags(m_drag_object.MouseFlags());
|
||||
delete m_drag_object;
|
||||
m_drag_object=NULL;
|
||||
}
|
||||
//--- succeed
|
||||
return(m_thumb.Pressed(false));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Calculate position by coordinate |
|
||||
//+------------------------------------------------------------------+
|
||||
int CScrollV::CalcPos(const int coord)
|
||||
{
|
||||
//--- calculate new position of the scrollbar
|
||||
int steps =m_max_pos-m_min_pos; // number of steps to change position
|
||||
int min_coord=m_dec.Bottom(); // minimum possible coordinate (corresponds to the m_min_pos value)
|
||||
int max_coord=m_inc.Top()-m_thumb.Height(); // maximum possible coordinate (corresponds to the m_max_pos value)
|
||||
//--- checkeng
|
||||
if(max_coord==min_coord)
|
||||
return(0);
|
||||
if(coord<min_coord || coord>max_coord)
|
||||
return(m_curr_pos);
|
||||
//---
|
||||
int new_pos=(int)MathRound((((double)(coord-min_coord))/(max_coord-min_coord))*steps); // new position
|
||||
//---
|
||||
return(new_pos);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CScrollH |
|
||||
//| Usage: class of horizontal scrollbar |
|
||||
//+------------------------------------------------------------------+
|
||||
class CScrollH : public CScroll
|
||||
{
|
||||
public:
|
||||
CScrollH(void);
|
||||
~CScrollH(void);
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
virtual bool CreateInc(void);
|
||||
virtual bool CreateDec(void);
|
||||
virtual bool CreateThumb(void);
|
||||
//--- internal event handlers
|
||||
virtual bool OnResize(void);
|
||||
virtual bool OnChangePos(void);
|
||||
//--- handlers of dragging
|
||||
virtual bool OnThumbDragStart(void);
|
||||
virtual bool OnThumbDragProcess(void);
|
||||
virtual bool OnThumbDragEnd(void);
|
||||
//--- calculate position by coordinate
|
||||
virtual int CalcPos(const int coord);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CScrollH::CScrollH(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CScrollH::~CScrollH(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create the "Increment" button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollH::CreateInc(void)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=Width()-CONTROLS_SCROLL_SIZE+CONTROLS_BORDER_WIDTH;
|
||||
int y1=CONTROLS_BORDER_WIDTH;
|
||||
int x2=x1+CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_BUTTON_SIZE;
|
||||
//--- create
|
||||
if(!m_inc.Create(m_chart_id,m_name+"Inc",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_inc.BmpNames("::res\\Right.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_inc))
|
||||
return(false);
|
||||
//--- property
|
||||
m_inc.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create the "Decrement" button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollH::CreateDec(void)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=CONTROLS_BORDER_WIDTH;
|
||||
int y1=CONTROLS_BORDER_WIDTH;
|
||||
int x2=x1+CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_BUTTON_SIZE;
|
||||
//--- create
|
||||
if(!m_dec.Create(m_chart_id,m_name+"Dec",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_dec.BmpNames("::res\\Left.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_dec))
|
||||
return(false);
|
||||
//--- property
|
||||
m_dec.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create scroll box |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollH::CreateThumb(void)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=CONTROLS_SCROLL_SIZE-CONTROLS_BORDER_WIDTH;
|
||||
int y1=CONTROLS_BORDER_WIDTH;
|
||||
int x2=x1+CONTROLS_SCROLL_THUMB_SIZE;
|
||||
int y2=y1+CONTROLS_BUTTON_SIZE;
|
||||
//--- create
|
||||
if(!m_thumb.Create(m_chart_id,m_name+"Thumb",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_thumb.BmpNames("::res\\ThumbHor.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_thumb))
|
||||
return(false);
|
||||
m_thumb.PropFlags(WND_PROP_FLAG_CAN_DRAG);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of changing current state |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollH::OnChangePos(void)
|
||||
{
|
||||
//--- check if scrolling is possible
|
||||
if(m_max_pos-m_min_pos<=0)
|
||||
return(Visible(false));
|
||||
else
|
||||
if(!Visible(true))
|
||||
return(false);
|
||||
//--- calculate new coordinated of the scrollbar
|
||||
int steps=m_max_pos-m_min_pos; // number of steps to change position
|
||||
int min_coord=m_dec.Right(); // minimum possible coordinate (corresponds to the m_min_pos value)
|
||||
int max_coord=m_inc.Left()-m_thumb.Width(); // maximum possible coordinate (corresponds to the m_max_pos value)
|
||||
int new_coord=min_coord+(max_coord-min_coord)*m_curr_pos/steps; // new coordinate
|
||||
//--- adjust the scroll box position
|
||||
return(m_thumb.Move(new_coord,m_thumb.Top()));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of resizing |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollH::OnResize(void)
|
||||
{
|
||||
//--- can not change the lateral size
|
||||
if(Height()!=CONTROLS_SCROLL_SIZE)
|
||||
m_rect.Height(CONTROLS_SCROLL_SIZE);
|
||||
//--- resize the scrollbar background
|
||||
if(!m_back.Size(Size()))
|
||||
return(false);
|
||||
//--- move the "Increment" button
|
||||
if(!m_inc.Move(Right()-CONTROLS_SCROLL_SIZE,m_inc.Top()))
|
||||
return(false);
|
||||
//--- adjust the scroll box position
|
||||
return(OnChangePos());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Start dragging the "slider" |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollH::OnThumbDragStart(void)
|
||||
{
|
||||
if(m_drag_object==NULL)
|
||||
{
|
||||
m_drag_object=new CDragWnd;
|
||||
if(m_drag_object==NULL)
|
||||
return(false);
|
||||
}
|
||||
//--- calculate coordinates
|
||||
int x1=m_thumb.Left()-CONTROLS_DRAG_SPACING;
|
||||
int y1=m_thumb.Top()-CONTROLS_DRAG_SPACING;
|
||||
int x2=m_thumb.Right()+CONTROLS_DRAG_SPACING;
|
||||
int y2=m_thumb.Bottom()+CONTROLS_DRAG_SPACING;
|
||||
//--- create
|
||||
m_drag_object.Create(m_chart_id,"",m_subwin,x1,y1,x2,y2);
|
||||
m_drag_object.PropFlags(WND_PROP_FLAG_CAN_DRAG);
|
||||
//--- îãðàíè÷åíèÿ
|
||||
m_drag_object.Limits(m_dec.Right()-CONTROLS_DRAG_SPACING,y1,m_inc.Left()+CONTROLS_DRAG_SPACING,y2);
|
||||
//--- set mouse params
|
||||
m_drag_object.MouseX(m_thumb.MouseX());
|
||||
m_drag_object.MouseY(m_thumb.MouseY());
|
||||
m_drag_object.MouseFlags(m_thumb.MouseFlags());
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Continue dragging the "slider" |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollH::OnThumbDragProcess(void)
|
||||
{
|
||||
//--- checking
|
||||
if(m_drag_object==NULL)
|
||||
return(false);
|
||||
//--- calculate coordinates
|
||||
int x=m_drag_object.Left()+CONTROLS_DRAG_SPACING;
|
||||
int y=m_drag_object.Top()+CONTROLS_DRAG_SPACING;
|
||||
//--- calculate new position
|
||||
int new_pos=CalcPos(x);
|
||||
if(new_pos!=m_curr_pos)
|
||||
{
|
||||
ushort event_id=(m_curr_pos<new_pos)?ON_SCROLL_INC:ON_SCROLL_DEC;
|
||||
m_curr_pos=new_pos;
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,event_id,m_id,0.0,m_name);
|
||||
}
|
||||
//--- move thumb
|
||||
m_thumb.Move(x,y);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| End dragging the "slider" |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CScrollH::OnThumbDragEnd(void)
|
||||
{
|
||||
if(m_drag_object!=NULL)
|
||||
{
|
||||
m_thumb.MouseFlags(m_drag_object.MouseFlags());
|
||||
delete m_drag_object;
|
||||
m_drag_object=NULL;
|
||||
}
|
||||
//--- succeed
|
||||
return(m_thumb.Pressed(false));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Calculate position by coordinate |
|
||||
//+------------------------------------------------------------------+
|
||||
int CScrollH::CalcPos(const int coord)
|
||||
{
|
||||
//--- calculate new position of the scrollbar
|
||||
int steps =m_max_pos-m_min_pos; // number of steps to change position
|
||||
int min_coord=m_dec.Right(); // minimum possible coordinate (corresponds to the m_min_pos value)
|
||||
int max_coord=m_inc.Left()-m_thumb.Width(); // maximum possible coordinate (corresponds to the m_max_pos value)
|
||||
//--- checkeng
|
||||
if(max_coord==min_coord)
|
||||
return(0);
|
||||
if(coord<min_coord || coord>max_coord)
|
||||
return(m_curr_pos);
|
||||
//---
|
||||
int new_pos=(int)MathRound((((double)(coord-min_coord))/(max_coord-min_coord))*steps); // new position
|
||||
//---
|
||||
return(new_pos);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,265 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SpinEdit.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndContainer.mqh"
|
||||
#include "Edit.mqh"
|
||||
#include "BmpButton.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resources |
|
||||
//+------------------------------------------------------------------+
|
||||
#resource "res\\SpinInc.bmp"
|
||||
#resource "res\\SpinDec.bmp"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSpinEdit |
|
||||
//| Usage: class that implements the "Up-Down" control |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSpinEdit : public CWndContainer
|
||||
{
|
||||
private:
|
||||
//--- dependent controls
|
||||
CEdit m_edit; // the entry field object
|
||||
CBmpButton m_inc; // the "Increment button" object
|
||||
CBmpButton m_dec; // the "Decrement button" object
|
||||
//--- adjusted parameters
|
||||
int m_min_value; // minimum value
|
||||
int m_max_value; // maximum value
|
||||
//--- state
|
||||
int m_value; // current value
|
||||
|
||||
public:
|
||||
CSpinEdit(void);
|
||||
~CSpinEdit(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- set up
|
||||
int MinValue(void) const { return(m_min_value); }
|
||||
void MinValue(const int value);
|
||||
int MaxValue(void) const { return(m_max_value); }
|
||||
void MaxValue(const int value);
|
||||
//--- state
|
||||
int Value(void) const { return(m_value); }
|
||||
bool Value(int value);
|
||||
//--- methods for working with files
|
||||
virtual bool Save(const int file_handle);
|
||||
virtual bool Load(const int file_handle);
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
virtual bool CreateEdit(void);
|
||||
virtual bool CreateInc(void);
|
||||
virtual bool CreateDec(void);
|
||||
//--- handlers of the dependent controls events
|
||||
virtual bool OnClickInc(void);
|
||||
virtual bool OnClickDec(void);
|
||||
//--- internal event handlers
|
||||
virtual bool OnChangeValue(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_BEGIN(CSpinEdit)
|
||||
ON_EVENT(ON_CLICK,m_inc,OnClickInc)
|
||||
ON_EVENT(ON_CLICK,m_dec,OnClickDec)
|
||||
EVENT_MAP_END(CWndContainer)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSpinEdit::CSpinEdit(void) : m_min_value(0),
|
||||
m_max_value(0),
|
||||
m_value(0)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSpinEdit::~CSpinEdit(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSpinEdit::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- check height
|
||||
if(y2-y1<CONTROLS_SPIN_MIN_HEIGHT)
|
||||
return(false);
|
||||
//--- call method of the parent class
|
||||
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create dependent controls
|
||||
if(!CreateEdit())
|
||||
return(false);
|
||||
if(!CreateInc())
|
||||
return(false);
|
||||
if(!CreateDec())
|
||||
return(false);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set current value |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSpinEdit::Value(int value)
|
||||
{
|
||||
//--- check value
|
||||
if(value<m_min_value)
|
||||
value=m_min_value;
|
||||
if(value>m_max_value)
|
||||
value=m_max_value;
|
||||
//--- if value was changed
|
||||
if(m_value!=value)
|
||||
{
|
||||
m_value=value;
|
||||
//--- call virtual handler
|
||||
return(OnChangeValue());
|
||||
}
|
||||
//--- value has not been changed
|
||||
return(false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSpinEdit::Save(const int file_handle)
|
||||
{
|
||||
//--- check
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//---
|
||||
FileWriteInteger(file_handle,m_value);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSpinEdit::Load(const int file_handle)
|
||||
{
|
||||
//--- check
|
||||
if(file_handle==INVALID_HANDLE)
|
||||
return(false);
|
||||
//---
|
||||
if(!FileIsEnding(file_handle))
|
||||
Value(FileReadInteger(file_handle));
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set minimum value |
|
||||
//+------------------------------------------------------------------+
|
||||
void CSpinEdit::MinValue(const int value)
|
||||
{
|
||||
//--- if value was changed
|
||||
if(m_min_value!=value)
|
||||
{
|
||||
m_min_value=value;
|
||||
//--- adjust the edit value
|
||||
Value(m_value);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set maximum value |
|
||||
//+------------------------------------------------------------------+
|
||||
void CSpinEdit::MaxValue(const int value)
|
||||
{
|
||||
//--- if value was changed
|
||||
if(m_max_value!=value)
|
||||
{
|
||||
m_max_value=value;
|
||||
//--- adjust the edit value
|
||||
Value(m_value);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create the edit field |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSpinEdit::CreateEdit(void)
|
||||
{
|
||||
//--- create
|
||||
if(!m_edit.Create(m_chart_id,m_name+"Edit",m_subwin,0,0,Width(),Height()))
|
||||
return(false);
|
||||
if(!m_edit.Text(""))
|
||||
return(false);
|
||||
if(!m_edit.ReadOnly(true))
|
||||
return(false);
|
||||
if(!Add(m_edit))
|
||||
return(false);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create the "Increment" button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSpinEdit::CreateInc(void)
|
||||
{
|
||||
//--- right align button (try to make equal offsets from top and bottom)
|
||||
int x1=Width()-(CONTROLS_BUTTON_SIZE+CONTROLS_SPIN_BUTTON_X_OFF);
|
||||
int y1=(Height()-2*CONTROLS_SPIN_BUTTON_SIZE)/2;
|
||||
int x2=x1+CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_SPIN_BUTTON_SIZE;
|
||||
//--- create
|
||||
if(!m_inc.Create(m_chart_id,m_name+"Inc",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_inc.BmpNames("::res\\SpinInc.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_inc))
|
||||
return(false);
|
||||
//--- property
|
||||
m_inc.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create the "Decrement" button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSpinEdit::CreateDec(void)
|
||||
{
|
||||
//--- right align button (try to make equal offsets from top and bottom)
|
||||
int x1=Width()-(CONTROLS_BUTTON_SIZE+CONTROLS_SPIN_BUTTON_X_OFF);
|
||||
int y1=(Height()-2*CONTROLS_SPIN_BUTTON_SIZE)/2+CONTROLS_SPIN_BUTTON_SIZE;
|
||||
int x2=x1+CONTROLS_BUTTON_SIZE;
|
||||
int y2=y1+CONTROLS_SPIN_BUTTON_SIZE;
|
||||
//--- create
|
||||
if(!m_dec.Create(m_chart_id,m_name+"Dec",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!m_dec.BmpNames("::res\\SpinDec.bmp"))
|
||||
return(false);
|
||||
if(!Add(m_dec))
|
||||
return(false);
|
||||
//--- property
|
||||
m_dec.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on the "increment" button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSpinEdit::OnClickInc(void)
|
||||
{
|
||||
//--- try to increment current value
|
||||
return(Value(m_value+1));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on the "decrement" button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSpinEdit::OnClickDec(void)
|
||||
{
|
||||
//--- try to decrement current value
|
||||
return(Value(m_value-1));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of changing current state |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSpinEdit::OnChangeValue(void)
|
||||
{
|
||||
//--- copy text to the edit field edit
|
||||
m_edit.Text(IntegerToString(m_value));
|
||||
//--- send notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,755 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Wnd.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "Rect.mqh"
|
||||
#include "Defines.mqh"
|
||||
#include <Object.mqh>
|
||||
class CDragWnd;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CWnd |
|
||||
//| Usage: base class of the control object that creates |
|
||||
//| control panels and indicator panels |
|
||||
//+------------------------------------------------------------------+
|
||||
class CWnd : public CObject
|
||||
{
|
||||
protected:
|
||||
//--- parameters of creation
|
||||
long m_chart_id; // chart ID
|
||||
int m_subwin; // chart subwindow
|
||||
string m_name; // object name
|
||||
//--- geometry
|
||||
CRect m_rect; // chart area
|
||||
//--- ID
|
||||
long m_id; // object ID
|
||||
//--- state flags
|
||||
int m_state_flags;
|
||||
//--- properties flags
|
||||
int m_prop_flags;
|
||||
//--- alignment
|
||||
int m_align_flags; // alignment flags
|
||||
int m_align_left; // fixed offset from left border
|
||||
int m_align_top; // fixed offset from top border
|
||||
int m_align_right; // fixed offset from right border
|
||||
int m_align_bottom; // fixed offset from bottom border
|
||||
//--- the last saved state of mouse
|
||||
int m_mouse_x; // X coordinate
|
||||
int m_mouse_y; // Y coordinate
|
||||
int m_mouse_flags; // state of buttons
|
||||
uint m_last_click; // last click time
|
||||
//--- drag object
|
||||
CDragWnd *m_drag_object; // pointer to the dragged object
|
||||
|
||||
public:
|
||||
CWnd(void);
|
||||
~CWnd(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- release memory
|
||||
virtual void Destroy(const int reason=0);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
virtual bool OnMouseEvent(const int x,const int y,const int flags);
|
||||
//--- naming (read only)
|
||||
string Name(void) const { return(m_name); }
|
||||
//--- access the contents of container
|
||||
int ControlsTotal(void) const { return(0); }
|
||||
CWnd* Control(const int ind) const { return(NULL); }
|
||||
virtual CWnd* ControlFind(const long id);
|
||||
//--- geometry
|
||||
const CRect Rect(void) const { return(m_rect); }
|
||||
int Left(void) const { return(m_rect.left); }
|
||||
virtual void Left(const int x) { m_rect.left=x; }
|
||||
int Top(void) const { return(m_rect.top); }
|
||||
virtual void Top(const int y) { m_rect.top=y; }
|
||||
int Right(void) const { return(m_rect.right); }
|
||||
virtual void Right(const int x) { m_rect.right=x; }
|
||||
int Bottom(void) const { return(m_rect.bottom); }
|
||||
virtual void Bottom(const int y) { m_rect.bottom=y; }
|
||||
int Width(void) const { return(m_rect.Width()); }
|
||||
virtual bool Width(const int w);
|
||||
int Height(void) const { return(m_rect.Height()); }
|
||||
virtual bool Height(const int h);
|
||||
CSize Size(void) const { return(m_rect.Size()); }
|
||||
virtual bool Size(const int w,const int h);
|
||||
virtual bool Size(const CSize &size);
|
||||
virtual bool Move(const int x,const int y);
|
||||
virtual bool Move(const CPoint &point);
|
||||
virtual bool Shift(const int dx,const int dy);
|
||||
bool Contains(const int x,const int y) const { return(m_rect.Contains(x,y)); }
|
||||
bool Contains(CWnd *control) const;
|
||||
//--- alignment
|
||||
void Alignment(const int flags,const int left,const int top,const int right,const int bottom);
|
||||
virtual bool Align(const CRect &rect);
|
||||
//--- ID
|
||||
virtual long Id(const long id);
|
||||
long Id(void) const { return(m_id); }
|
||||
//--- state
|
||||
bool IsEnabled(void) const { return(IS_ENABLED); }
|
||||
virtual bool Enable(void);
|
||||
virtual bool Disable(void);
|
||||
bool IsVisible(void) const { return(IS_VISIBLE); }
|
||||
virtual bool Visible(const bool flag);
|
||||
virtual bool Show(void);
|
||||
virtual bool Hide(void);
|
||||
bool IsActive(void) const { return(IS_ACTIVE); }
|
||||
virtual bool Activate(void);
|
||||
virtual bool Deactivate(void);
|
||||
//--- state flags
|
||||
int StateFlags(void) const { return(m_state_flags); }
|
||||
void StateFlags(const int flags) { m_state_flags=flags; }
|
||||
void StateFlagsSet(const int flags) { m_state_flags|=flags; }
|
||||
void StateFlagsReset(const int flags) { m_state_flags&=~flags; }
|
||||
//--- properties flags
|
||||
int PropFlags(void) const { return(m_prop_flags); }
|
||||
void PropFlags(const int flags) { m_prop_flags=flags; }
|
||||
void PropFlagsSet(const int flags) { m_prop_flags|=flags; }
|
||||
void PropFlagsReset(const int flags) { m_prop_flags&=~flags; }
|
||||
//--- for mouse operations
|
||||
int MouseX(void) const { return(m_mouse_x); }
|
||||
void MouseX(const int value) { m_mouse_x=value; }
|
||||
int MouseY(void) const { return(m_mouse_y); }
|
||||
void MouseY(const int value) { m_mouse_y=value; }
|
||||
int MouseFlags(void) const { return(m_mouse_flags); }
|
||||
virtual void MouseFlags(const int value) { m_mouse_flags=value; }
|
||||
bool MouseFocusKill(const long id=CONTROLS_INVALID_ID);
|
||||
bool BringToTop(void);
|
||||
|
||||
protected:
|
||||
//--- internal event handlers
|
||||
virtual bool OnCreate(void) { return(true); }
|
||||
virtual bool OnDestroy(void) { return(true); }
|
||||
virtual bool OnMove(void) { return(true); }
|
||||
virtual bool OnResize(void) { return(true); }
|
||||
virtual bool OnEnable(void) { return(true); }
|
||||
virtual bool OnDisable(void) { return(true); }
|
||||
virtual bool OnShow(void) { return(true); }
|
||||
virtual bool OnHide(void) { return(true); }
|
||||
virtual bool OnActivate(void) { return(true); }
|
||||
virtual bool OnDeactivate(void) { return(true); }
|
||||
virtual bool OnClick(void);
|
||||
virtual bool OnDblClick(void);
|
||||
virtual bool OnChange(void) { return(true); }
|
||||
//--- mouse event handlers
|
||||
virtual bool OnMouseDown(void);
|
||||
virtual bool OnMouseUp(void);
|
||||
//--- handlers of dragging
|
||||
virtual bool OnDragStart(void);
|
||||
virtual bool OnDragProcess(const int x,const int y);
|
||||
virtual bool OnDragEnd(void);
|
||||
//--- methods for drag-object
|
||||
virtual bool DragObjectCreate(void) { return(false); }
|
||||
virtual bool DragObjectDestroy(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
|
||||
{
|
||||
if((id!=CHARTEVENT_MOUSE_MOVE))
|
||||
return(false);
|
||||
if(!IS_VISIBLE)
|
||||
return(false);
|
||||
int x=(int)lparam;
|
||||
int y=(int)dparam;
|
||||
int flags=(int)StringToInteger(sparam);
|
||||
//---
|
||||
if(m_drag_object!=NULL)
|
||||
return(m_drag_object.OnMouseEvent(x,y,flags));
|
||||
//---
|
||||
return(OnMouseEvent(x,y,flags));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of mouse events |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::OnMouseEvent(const int x,const int y,const int flags)
|
||||
{
|
||||
if(!Contains(x,y))
|
||||
{
|
||||
//--- if cursor is not inside the element and this element is active - deactivate
|
||||
if(IS_ACTIVE)
|
||||
{
|
||||
//--- reset state and coordinates
|
||||
m_mouse_x =0;
|
||||
m_mouse_y =0;
|
||||
m_mouse_flags=MOUSE_INVALID_FLAGS;
|
||||
//--- deactivate
|
||||
Deactivate();
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
//--- check the state of the left mouse button
|
||||
if((flags&MOUSE_LEFT)!=0)
|
||||
{
|
||||
//--- left mouse button is pressed
|
||||
if(m_mouse_flags==MOUSE_INVALID_FLAGS)
|
||||
{
|
||||
//--- but not in this control (i.e., cursor entered the element with mouse button pressed)
|
||||
//--- activate the control, but there will be no click
|
||||
if(!IS_ACTIVE)
|
||||
{
|
||||
//--- generate event
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_MOUSE_FOCUS_SET,m_id,0.0,m_name);
|
||||
//--- activate
|
||||
return(Activate());
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
if((m_mouse_flags&MOUSE_LEFT)!=0)
|
||||
{
|
||||
//--- mouse button has already been pressed
|
||||
if(IS_CAN_DRAG)
|
||||
return(OnDragProcess(x,y));
|
||||
if(IS_CLICKS_BY_PRESS)
|
||||
{
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CLICK,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- mouse button has been released (pressing)
|
||||
//--- save the state and coordinates
|
||||
m_mouse_flags=flags;
|
||||
m_mouse_x =x;
|
||||
m_mouse_y =y;
|
||||
//--- call the handler
|
||||
return(OnMouseDown());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- left mouse button is released
|
||||
if(m_mouse_flags==MOUSE_INVALID_FLAGS)
|
||||
{
|
||||
//--- cursor entered the control with mouse button released
|
||||
//--- activate control and save state to the member
|
||||
m_mouse_flags=flags;
|
||||
//--- generate event
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_MOUSE_FOCUS_SET,m_id,0.0,m_name);
|
||||
//--- activate
|
||||
return(Activate());
|
||||
}
|
||||
if((m_mouse_flags&MOUSE_LEFT)!=0)
|
||||
{
|
||||
//--- mouse button has been pressed (clicking)
|
||||
//--- save the state and coordinates
|
||||
m_mouse_flags=flags;
|
||||
m_mouse_x =x;
|
||||
m_mouse_y =y;
|
||||
//--- call the handler
|
||||
return(OnMouseUp());
|
||||
}
|
||||
}
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CWnd::CWnd(void) : m_chart_id(CONTROLS_INVALID_ID),
|
||||
m_subwin(CONTROLS_INVALID_ID),
|
||||
m_name(NULL),
|
||||
m_id(CONTROLS_INVALID_ID),
|
||||
m_state_flags(WND_STATE_FLAG_ENABLE+WND_STATE_FLAG_VISIBLE),
|
||||
m_prop_flags(0),
|
||||
m_align_flags(WND_ALIGN_NONE),
|
||||
m_align_left(0),
|
||||
m_align_top(0),
|
||||
m_align_right(0),
|
||||
m_align_bottom(0),
|
||||
m_mouse_x(0),
|
||||
m_mouse_y(0),
|
||||
m_mouse_flags(MOUSE_INVALID_FLAGS),
|
||||
m_last_click(0),
|
||||
m_drag_object(NULL)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CWnd::~CWnd(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- attach to chart
|
||||
m_chart_id=chart;
|
||||
m_name =name;
|
||||
m_subwin =subwin;
|
||||
//--- set coordinates of area
|
||||
Left(x1);
|
||||
Top(y1);
|
||||
Right(x2);
|
||||
Bottom(y2);
|
||||
//--- always successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destruction of the control |
|
||||
//+------------------------------------------------------------------+
|
||||
void CWnd::Destroy(const int reason)
|
||||
{
|
||||
//--- call virtual event handler
|
||||
if(OnDestroy())
|
||||
m_name="";
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Find control by specified ID |
|
||||
//+------------------------------------------------------------------+
|
||||
CWnd* CWnd::ControlFind(const long id)
|
||||
{
|
||||
CWnd *result=NULL;
|
||||
//--- check
|
||||
if(id==m_id)
|
||||
result=GetPointer(this);
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Change width of control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Width(const int w)
|
||||
{
|
||||
//--- change width
|
||||
m_rect.Width(w);
|
||||
//--- call virtual event handler
|
||||
return(OnResize());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Change height of control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Height(const int h)
|
||||
{
|
||||
//--- change height
|
||||
m_rect.Height(h);
|
||||
//--- call virtual event handler
|
||||
return(OnResize());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resize control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Size(const int w,const int h)
|
||||
{
|
||||
//--- change size
|
||||
m_rect.Size(w,h);
|
||||
//--- call virtual event handler
|
||||
return(OnResize());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resize control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Size(const CSize &size)
|
||||
{
|
||||
//--- change size
|
||||
m_rect.Size(size);
|
||||
//--- call virtual event handler
|
||||
return(OnResize());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Absolute movement of the control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Move(const int x,const int y)
|
||||
{
|
||||
//--- moving
|
||||
m_rect.Move(x,y);
|
||||
//--- call virtual event handler
|
||||
return(OnMove());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Absolute movement of the control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Move(const CPoint &point)
|
||||
{
|
||||
//--- moving
|
||||
m_rect.Move(point);
|
||||
//--- call virtual event handler
|
||||
return(OnMove());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Relative movement of the control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Shift(const int dx,const int dy)
|
||||
{
|
||||
//--- moving
|
||||
m_rect.Shift(dx,dy);
|
||||
//--- call virtual event handler
|
||||
return(OnMove());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check contains |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Contains(CWnd *control) const
|
||||
{
|
||||
//--- check
|
||||
if(control==NULL)
|
||||
return(false);
|
||||
//--- result
|
||||
return(Contains(control.Left(),control.Top()) && Contains(control.Right(),control.Bottom()));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Enables event handling by the control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Enable(void)
|
||||
{
|
||||
//--- if there are now changes, then succeed
|
||||
if(IS_ENABLED)
|
||||
return(true);
|
||||
//--- change flag
|
||||
StateFlagsSet(WND_STATE_FLAG_ENABLE);
|
||||
//--- call virtual event handler
|
||||
return(OnEnable());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Disables event handling by the control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Disable(void)
|
||||
{
|
||||
//--- if there are now changes, then succeed
|
||||
if(!IS_ENABLED)
|
||||
return(true);
|
||||
//--- change flag
|
||||
StateFlagsReset(WND_STATE_FLAG_ENABLE);
|
||||
//--- call virtual event handler
|
||||
return(OnDisable());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set the "object is visible" flag for the control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Visible(const bool flag)
|
||||
{
|
||||
//--- if there are now changes, then succeed
|
||||
if(IS_VISIBLE==flag)
|
||||
return(true);
|
||||
//--- call virtual event handler
|
||||
return(flag ? Show() : Hide());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Makes the control visible |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Show(void)
|
||||
{
|
||||
//--- change flag
|
||||
StateFlagsSet(WND_STATE_FLAG_VISIBLE);
|
||||
//--- call virtual event handler
|
||||
return(OnShow());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Makes the control hidden |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Hide(void)
|
||||
{
|
||||
//--- change flag
|
||||
StateFlagsReset(WND_STATE_FLAG_VISIBLE);
|
||||
//--- call virtual event handler
|
||||
return(OnHide());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Makes the control active |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Activate(void)
|
||||
{
|
||||
//--- if there are now changes, then succeed
|
||||
if(IS_ACTIVE)
|
||||
return(true);
|
||||
//--- change flag
|
||||
StateFlagsSet(WND_STATE_FLAG_ACTIVE);
|
||||
//--- call virtual event handler
|
||||
return(OnActivate());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Makes the control inactive |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Deactivate(void)
|
||||
{
|
||||
//--- if there are now changes, then succeed
|
||||
if(!IS_ACTIVE)
|
||||
return(true);
|
||||
//--- change flag
|
||||
StateFlagsReset(WND_STATE_FLAG_ACTIVE);
|
||||
//--- call virtual event handler
|
||||
return(OnDeactivate());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set ID of control |
|
||||
//+------------------------------------------------------------------+
|
||||
long CWnd::Id(const long id)
|
||||
{
|
||||
m_id=id;
|
||||
//--- always use only one ID
|
||||
return(1);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set parameters of alignment |
|
||||
//+------------------------------------------------------------------+
|
||||
void CWnd::Alignment(const int flags,const int left,const int top,const int right,const int bottom)
|
||||
{
|
||||
m_align_flags =flags;
|
||||
m_align_left =left;
|
||||
m_align_top =top;
|
||||
m_align_right =right;
|
||||
m_align_bottom=bottom;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Align element in specified chart area |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::Align(const CRect &rect)
|
||||
{
|
||||
int new_value=0;
|
||||
//--- check
|
||||
if(m_align_flags==WND_ALIGN_NONE)
|
||||
return(true);
|
||||
//--- we are interested only in alignment by right and bottom borders,
|
||||
//--- as left and right borders are processed in the OnMove()
|
||||
if((m_align_flags&WND_ALIGN_RIGHT)!=0)
|
||||
{
|
||||
//--- there is alignment by right border,
|
||||
if((m_align_flags&WND_ALIGN_LEFT)!=0)
|
||||
{
|
||||
//--- and by left border (change size)
|
||||
new_value=rect.Width()-m_align_left-m_align_right;
|
||||
if(!Size(new_value,Height()))
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- no alignment by left border (move)
|
||||
new_value=rect.right-Width()-m_align_right;
|
||||
if(!Move(new_value,Top()))
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
if((m_align_flags&WND_ALIGN_BOTTOM)!=0)
|
||||
{
|
||||
//--- there is alignment by bottom border,
|
||||
if((m_align_flags&WND_ALIGN_TOP)!=0)
|
||||
{
|
||||
//--- and by top border (change size)
|
||||
new_value=rect.Height()-m_align_top-m_align_bottom;
|
||||
if(!Size(Width(),new_value))
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- no alignment by top border (move)
|
||||
new_value=rect.bottom-Height()-m_align_bottom;
|
||||
if(!Move(Left(),new_value))
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Remove the mouse focus from control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::MouseFocusKill(const long id)
|
||||
{
|
||||
//--- check
|
||||
if(id==m_id)
|
||||
return(false);
|
||||
//--- reset flag
|
||||
Deactivate();
|
||||
//--- clean
|
||||
m_mouse_x =0;
|
||||
m_mouse_y =0;
|
||||
m_mouse_flags=MOUSE_INVALID_FLAGS;
|
||||
//--- call the handler
|
||||
return(OnDeactivate());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Increases the priority of an element |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::BringToTop(void)
|
||||
{
|
||||
//--- generate event
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_BRING_TO_TOP,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "click" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::OnClick(void)
|
||||
{
|
||||
//--- send notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CLICK,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "doubl click" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::OnDblClick(void)
|
||||
{
|
||||
//--- send notification
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_DBL_CLICK,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of click on the left mouse button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::OnMouseDown(void)
|
||||
{
|
||||
if(IS_CAN_DRAG)
|
||||
return(OnDragStart());
|
||||
if(IS_CLICKS_BY_PRESS)
|
||||
return(OnClick());
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of releasing the left mouse button |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::OnMouseUp(void)
|
||||
{
|
||||
if(IS_CAN_DBL_CLICK)
|
||||
{
|
||||
uint last_time=GetTickCount();
|
||||
if(m_last_click==0 || last_time-m_last_click>CONTROLS_DBL_CLICK_TIME)
|
||||
{
|
||||
m_last_click=(last_time==0) ? 1 : last_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_last_click=0;
|
||||
return(OnDblClick());
|
||||
}
|
||||
}
|
||||
if(IS_CAN_DRAG)
|
||||
return(OnDragEnd());
|
||||
if(!IS_CLICKS_BY_PRESS)
|
||||
return(OnClick());
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the control dragging start |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::OnDragStart(void)
|
||||
{
|
||||
if(!IS_CAN_DRAG)
|
||||
return(true);
|
||||
//--- disable scrolling of chart with mouse
|
||||
ChartSetInteger(m_chart_id,CHART_MOUSE_SCROLL,false);
|
||||
//--- generate event
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_DRAG_START,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of control dragging process |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::OnDragProcess(const int x,const int y)
|
||||
{
|
||||
Shift(x-m_mouse_x,y-m_mouse_y);
|
||||
//--- save
|
||||
m_mouse_x=x;
|
||||
m_mouse_y=y;
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the control dragging end |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::OnDragEnd(void)
|
||||
{
|
||||
if(!IS_CAN_DRAG)
|
||||
return(true);
|
||||
//--- enable scrolling of chart with mouse
|
||||
ChartSetInteger(m_chart_id,CHART_MOUSE_SCROLL,true);
|
||||
//--- generate event
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_DRAG_END,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destroy the dragged object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWnd::DragObjectDestroy(void)
|
||||
{
|
||||
if(m_drag_object!=NULL)
|
||||
{
|
||||
delete m_drag_object;
|
||||
m_drag_object=NULL;
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CDragWnd |
|
||||
//| Usage: base class for drag |
|
||||
//+------------------------------------------------------------------+
|
||||
class CDragWnd : public CWnd
|
||||
{
|
||||
protected:
|
||||
int m_limit_left; // left constraint
|
||||
int m_limit_top; // top constraint
|
||||
int m_limit_right; // right constraint
|
||||
int m_limit_bottom; // bottom constraint
|
||||
|
||||
public:
|
||||
CDragWnd(void);
|
||||
~CDragWnd(void);
|
||||
//--- constraints
|
||||
void Limits(const int l,const int t,const int r,const int b);
|
||||
|
||||
protected:
|
||||
virtual bool OnDragProcess(const int x,const int y);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CDragWnd::CDragWnd(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CDragWnd::~CDragWnd(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constrain the control dragging |
|
||||
//+------------------------------------------------------------------+
|
||||
void CDragWnd::Limits(const int l,const int t,const int r,const int b)
|
||||
{
|
||||
//--- save
|
||||
m_limit_left =l;
|
||||
m_limit_top =t;
|
||||
m_limit_right =r;
|
||||
m_limit_bottom=b;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of control dragging process |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CDragWnd::OnDragProcess(const int x,const int y)
|
||||
{
|
||||
int dx=x-m_mouse_x;
|
||||
int dy=y-m_mouse_y;
|
||||
//--- check shift
|
||||
if(Right()+dx>m_limit_right)
|
||||
dx=m_limit_right-Right();
|
||||
if(Left()+dx<m_limit_left)
|
||||
dx=m_limit_left-Left();
|
||||
if(Bottom()+dy>m_limit_bottom)
|
||||
dy=m_limit_bottom-Bottom();
|
||||
if(Top()+dy<m_limit_top)
|
||||
dy=m_limit_top-Top();
|
||||
//--- shift
|
||||
Shift(dx,dy);
|
||||
//--- save
|
||||
m_mouse_x=x;
|
||||
m_mouse_y=y;
|
||||
//--- generate event
|
||||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_DRAG_PROCESS,m_id,0.0,m_name);
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,308 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| WndClient.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "WndContainer.mqh"
|
||||
#include "Panel.mqh"
|
||||
#include "Scrolls.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CWndClient |
|
||||
//| Usage: base class to create areas with |
|
||||
//| the scrollbars |
|
||||
//+------------------------------------------------------------------+
|
||||
class CWndClient : public CWndContainer
|
||||
{
|
||||
protected:
|
||||
//--- flags
|
||||
bool m_v_scrolled; // "vertical scrolling is possible" flag
|
||||
bool m_h_scrolled; // "horizontal scrolling is possible" flag
|
||||
//--- dependent controls
|
||||
CPanel m_background; // the "scrollbar background" object
|
||||
CScrollV m_scroll_v; // the vertical scrollbar object
|
||||
CScrollH m_scroll_h; // the horizontal scrollbar object
|
||||
|
||||
public:
|
||||
CWndClient(void);
|
||||
~CWndClient(void);
|
||||
//--- create
|
||||
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- parameters
|
||||
virtual bool ColorBackground(const color value) { return(m_background.ColorBackground(value)); }
|
||||
virtual bool ColorBorder(const color value) { return(m_background.ColorBorder(value)); }
|
||||
virtual bool BorderType(const ENUM_BORDER_TYPE flag) { return(m_background.BorderType(flag)); }
|
||||
//--- settings
|
||||
virtual bool VScrolled(void) { return(m_v_scrolled); }
|
||||
virtual bool VScrolled(const bool flag);
|
||||
virtual bool HScrolled(void) { return(m_h_scrolled); }
|
||||
virtual bool HScrolled(const bool flag);
|
||||
//--- ID
|
||||
virtual long Id(const long id);
|
||||
virtual long Id(void) const { return(CWnd::Id()); }
|
||||
//--- state
|
||||
virtual bool Show(void);
|
||||
|
||||
protected:
|
||||
//--- create dependent controls
|
||||
virtual bool CreateBack(void);
|
||||
virtual bool CreateScrollV(void);
|
||||
virtual bool CreateScrollH(void);
|
||||
//--- internal event handlers
|
||||
virtual bool OnResize(void);
|
||||
//--- handlers of the dependent controls events
|
||||
virtual bool OnVScrollShow(void) { return(true); }
|
||||
virtual bool OnVScrollHide(void) { return(true); }
|
||||
virtual bool OnHScrollShow(void) { return(true); }
|
||||
virtual bool OnHScrollHide(void) { return(true); }
|
||||
virtual bool OnScrollLineDown(void) { return(true); }
|
||||
virtual bool OnScrollLineUp(void) { return(true); }
|
||||
virtual bool OnScrollLineLeft(void) { return(true); }
|
||||
virtual bool OnScrollLineRight(void) { return(true); }
|
||||
//--- resize
|
||||
virtual bool Rebound(const CRect &rect);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
EVENT_MAP_BEGIN(CWndClient)
|
||||
ON_NAMED_EVENT(ON_SHOW,m_scroll_v,OnVScrollShow)
|
||||
ON_NAMED_EVENT(ON_HIDE,m_scroll_v,OnVScrollHide)
|
||||
ON_EVENT(ON_SCROLL_DEC,m_scroll_v,OnScrollLineUp)
|
||||
ON_EVENT(ON_SCROLL_INC,m_scroll_v,OnScrollLineDown)
|
||||
ON_NAMED_EVENT(ON_SHOW,m_scroll_h,OnHScrollShow)
|
||||
ON_NAMED_EVENT(ON_HIDE,m_scroll_h,OnHScrollHide)
|
||||
ON_EVENT(ON_SCROLL_DEC,m_scroll_h,OnScrollLineLeft)
|
||||
ON_EVENT(ON_SCROLL_INC,m_scroll_h,OnScrollLineRight)
|
||||
EVENT_MAP_END(CWndContainer)
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CWndClient::CWndClient(void) : m_v_scrolled(false),
|
||||
m_h_scrolled(false)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CWndClient::~CWndClient(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create a control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndClient::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
//--- create dependent controls
|
||||
if(!CreateBack())
|
||||
return(false);
|
||||
if(m_v_scrolled && !CreateScrollV())
|
||||
return(false);
|
||||
if(m_h_scrolled && !CreateScrollH())
|
||||
return(false);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create scrollbar background |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndClient::CreateBack(void)
|
||||
{
|
||||
//--- create
|
||||
if(!m_background.Create(m_chart_id,m_name+"Back",m_subwin,0,0,Width(),Height()))
|
||||
return(false);
|
||||
if(!m_background.ColorBorder(CONTROLS_CLIENT_COLOR_BORDER))
|
||||
return(false);
|
||||
if(!m_background.ColorBackground(CONTROLS_CLIENT_COLOR_BG))
|
||||
return(false);
|
||||
if(!Add(m_background))
|
||||
return(false);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create vertical scrollbar |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndClient::CreateScrollV(void)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=Width()-CONTROLS_SCROLL_SIZE-CONTROLS_BORDER_WIDTH;
|
||||
int y1=CONTROLS_BORDER_WIDTH;
|
||||
int x2=Width()-CONTROLS_BORDER_WIDTH;
|
||||
int y2=Height()-CONTROLS_BORDER_WIDTH;
|
||||
if(m_h_scrolled) y2-=CONTROLS_SCROLL_SIZE;
|
||||
//--- create
|
||||
if(!m_scroll_v.Create(m_chart_id,m_name+"VScroll",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!Add(m_scroll_v))
|
||||
return(false);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create horizontal scrollbar |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndClient::CreateScrollH(void)
|
||||
{
|
||||
//--- calculate coordinates
|
||||
int x1=CONTROLS_BORDER_WIDTH;
|
||||
int y1=Height()-CONTROLS_SCROLL_SIZE-CONTROLS_BORDER_WIDTH;
|
||||
int x2=Width()-CONTROLS_BORDER_WIDTH;
|
||||
int y2=Height()-CONTROLS_BORDER_WIDTH;
|
||||
if(m_v_scrolled) x2-=CONTROLS_SCROLL_SIZE;
|
||||
//--- create
|
||||
if(!m_scroll_h.Create(m_chart_id,m_name+"HScroll",m_subwin,x1,y1,x2,y2))
|
||||
return(false);
|
||||
if(!Add(m_scroll_h))
|
||||
return(false);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set up vertical scrollbar |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndClient::VScrolled(const bool flag)
|
||||
{
|
||||
if(m_v_scrolled==flag)
|
||||
return(true);
|
||||
//--- there are changes
|
||||
int d_size=0;
|
||||
if(flag)
|
||||
{
|
||||
//--- create vertical scrollbar
|
||||
if(!CreateScrollV())
|
||||
return(false);
|
||||
//--- need to shorten horizontal scrollbar (if there is one)
|
||||
d_size=-CONTROLS_SCROLL_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- delete vertical scrollbar
|
||||
m_scroll_v.Destroy();
|
||||
if(!Delete(m_scroll_v))
|
||||
return(false);
|
||||
//--- need to lengthen horizontal scrollbar (if there is one)
|
||||
d_size=CONTROLS_SCROLL_SIZE;
|
||||
}
|
||||
m_v_scrolled=flag;
|
||||
//--- change width of horizontal scrollbar (if there is one)
|
||||
if(m_h_scrolled)
|
||||
{
|
||||
if(!m_scroll_h.Width(m_scroll_h.Width()+d_size))
|
||||
return(false);
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set up horizontal scrollbar |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndClient::HScrolled(const bool flag)
|
||||
{
|
||||
if(m_h_scrolled==flag)
|
||||
return(true);
|
||||
//--- there are changes
|
||||
int d_size=0;
|
||||
if(flag)
|
||||
{
|
||||
//--- create horizontal scrollbar
|
||||
if(!CreateScrollH())
|
||||
return(false);
|
||||
//--- need to shorten vertical scrollbar (if there is one)
|
||||
d_size=-CONTROLS_SCROLL_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- delete horizontal scrollbar
|
||||
m_scroll_h.Destroy();
|
||||
if(!Delete(m_scroll_h))
|
||||
return(false);
|
||||
//--- need to lengthen vertical scrollbar (if there is one)
|
||||
d_size=CONTROLS_SCROLL_SIZE;
|
||||
}
|
||||
m_h_scrolled=flag;
|
||||
//--- change width of vertical scrollbar (if there is one)
|
||||
if(m_v_scrolled)
|
||||
{
|
||||
if(!m_scroll_v.Height(m_scroll_v.Height()+d_size))
|
||||
return(false);
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set ID of control |
|
||||
//+------------------------------------------------------------------+
|
||||
long CWndClient::Id(const long id)
|
||||
{
|
||||
//--- reserve ID for container
|
||||
long id_used=CWndContainer::Id(id);
|
||||
//---
|
||||
if(!m_v_scrolled)
|
||||
id_used+=m_scroll_v.Id(id+id_used);
|
||||
if(!m_h_scrolled)
|
||||
id_used+=m_scroll_h.Id(id+id_used);
|
||||
//--- return number of used IDs
|
||||
return(id_used);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Makes the control visible |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndClient::Show(void)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
CWndContainer::Show();
|
||||
//---
|
||||
if(!m_v_scrolled)
|
||||
m_scroll_v.Hide();
|
||||
if(!m_h_scrolled)
|
||||
m_scroll_h.Hide();
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of resizing |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndClient::OnResize(void)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
if(!CWndContainer::OnResize())
|
||||
return(false);
|
||||
//--- resize background
|
||||
int d_size=0;
|
||||
m_background.Width(Width());
|
||||
m_background.Height(Height());
|
||||
//---
|
||||
if(m_v_scrolled)
|
||||
{
|
||||
//--- move vertical scrollbar
|
||||
m_scroll_v.Move(Right()-CONTROLS_SCROLL_SIZE,Top());
|
||||
//--- modify vertical scrollbar
|
||||
d_size=(m_h_scrolled) ? CONTROLS_SCROLL_SIZE : 0;
|
||||
m_scroll_v.Height(Height()-d_size);
|
||||
}
|
||||
if(m_h_scrolled)
|
||||
{
|
||||
//--- move horizontal scrollbar
|
||||
m_scroll_h.Move(Left(),Bottom()-CONTROLS_SCROLL_SIZE);
|
||||
//--- modify horizontal scrollbar
|
||||
d_size=(m_v_scrolled) ? CONTROLS_SCROLL_SIZE : 0;
|
||||
m_scroll_h.Width(Width()-d_size);
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Resize |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndClient::Rebound(const CRect &rect)
|
||||
{
|
||||
m_rect.SetBound(rect);
|
||||
//--- call virtual event handler
|
||||
return(OnResize());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,473 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| WndContainer.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "Wnd.mqh"
|
||||
#include <Arrays\ArrayObj.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CWndContainer |
|
||||
//| Usage: base class of the combined control |
|
||||
//+------------------------------------------------------------------+
|
||||
class CWndContainer : public CWnd
|
||||
{
|
||||
private:
|
||||
CArrayObj m_controls; // container of the control
|
||||
|
||||
public:
|
||||
CWndContainer(void);
|
||||
~CWndContainer(void);
|
||||
//--- release memory
|
||||
virtual void Destroy(const int reason=0);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
virtual bool OnMouseEvent(const int x,const int y,const int flags);
|
||||
//--- access the contents of container
|
||||
int ControlsTotal(void) const { return(m_controls.Total()); }
|
||||
CWnd* Control(const int ind) const { return(dynamic_cast<CWnd *>(m_controls.At(ind))); }
|
||||
virtual CWnd* ControlFind(const long id);
|
||||
//--- for mouse cursor focus
|
||||
virtual bool MouseFocusKill(const long id=-1);
|
||||
//--- fill
|
||||
bool Add(CWnd *control);
|
||||
bool Add(CWnd &control);
|
||||
//--- underflowing
|
||||
bool Delete(CWnd *control);
|
||||
bool Delete(CWnd &control);
|
||||
//--- geometry
|
||||
virtual bool Move(const int x,const int y);
|
||||
virtual bool Move(const CPoint &point);
|
||||
virtual bool Shift(const int dx,const int dy);
|
||||
//--- ID
|
||||
virtual long Id(const long id);
|
||||
long Id(void) const { return(CWnd::Id()); }
|
||||
//--- state
|
||||
virtual bool Enable(void);
|
||||
virtual bool Disable(void);
|
||||
virtual bool Show(void);
|
||||
virtual bool Hide(void);
|
||||
//--- methods for working with files
|
||||
virtual bool Save(const int file_handle);
|
||||
virtual bool Load(const int file_handle);
|
||||
|
||||
protected:
|
||||
//--- internal event handlers
|
||||
virtual bool OnResize(void);
|
||||
virtual bool OnActivate(void);
|
||||
virtual bool OnDeactivate(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
|
||||
{
|
||||
//--- if an object is being dragged, pass control to the special drag object
|
||||
if(m_drag_object!=NULL && m_drag_object.OnEvent(id,lparam,dparam,sparam))
|
||||
return(true);
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=total-1;i>=0;i--)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
if(control.OnEvent(id,lparam,dparam,sparam))
|
||||
return(true);
|
||||
}
|
||||
//--- not handled
|
||||
return(false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of mouse events |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::OnMouseEvent(const int x,const int y,const int flags)
|
||||
{
|
||||
if(!IS_VISIBLE)
|
||||
return(false);
|
||||
//--- if an object is being dragged, pass control to the special drag object
|
||||
if(m_drag_object!=NULL && m_drag_object.OnMouseEvent(x,y,flags))
|
||||
return(true);
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=total-1;i>=0;i--)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
if(control.OnMouseEvent(x,y,flags))
|
||||
return(true);
|
||||
}
|
||||
//--- call of the method of the parent class
|
||||
return(CWnd::OnMouseEvent(x,y,flags));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CWndContainer::CWndContainer(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CWndContainer::~CWndContainer(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Delete group of controls |
|
||||
//+------------------------------------------------------------------+
|
||||
void CWndContainer::Destroy(const int reason)
|
||||
{
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(0);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
control.Destroy();
|
||||
m_controls.Delete(0);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Find control by specified ID |
|
||||
//+------------------------------------------------------------------+
|
||||
CWnd* CWndContainer::ControlFind(const long id)
|
||||
{
|
||||
CWnd *result=CWnd::ControlFind(id);
|
||||
//---
|
||||
if(result!=NULL)
|
||||
return(result);
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
result=control.ControlFind(id);
|
||||
if(result!=NULL)
|
||||
break;
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Remove the mouse focus from control |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::MouseFocusKill(const long id=-1)
|
||||
{
|
||||
if(!IS_ACTIVE)
|
||||
return(false);
|
||||
Deactivate();
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
control.MouseFocusKill();
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Add control to the group (by pointer) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::Add(CWnd *control)
|
||||
{
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
return(false);
|
||||
//--- correct the coordinates of added control
|
||||
control.Shift(Left(),Top());
|
||||
//--- "projecting" the group flag "visibility" to the added element
|
||||
if(IS_VISIBLE && control.IsVisible())
|
||||
{
|
||||
//--- element will be "visible" only if the group is "visible" and the element is completely "within" this group
|
||||
control.Visible(Contains(control));
|
||||
}
|
||||
else
|
||||
control.Hide();
|
||||
//--- "projecting" the group flag "enabled" to the added element
|
||||
if(IS_ENABLED)
|
||||
control.Enable();
|
||||
else
|
||||
control.Disable();
|
||||
//--- adding
|
||||
return(m_controls.Add(control));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Add control to the group (by reference) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::Add(CWnd &control)
|
||||
{
|
||||
//--- add by pointer
|
||||
return(Add((CWnd*)GetPointer(control)));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Delete control from the group (by pointer) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::Delete(CWnd *control)
|
||||
{
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
return(false);
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *pointer=Control(i);
|
||||
//--- check of pointer
|
||||
if(pointer==NULL)
|
||||
continue;
|
||||
//--- delete item from group
|
||||
if(pointer==control)
|
||||
return(m_controls.Delete(i));
|
||||
}
|
||||
//--- failure
|
||||
return(false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Delete control from the group (by reference) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::Delete(CWnd &control)
|
||||
{
|
||||
//--- delete by pointer
|
||||
return(Delete((CWnd*)GetPointer(control)));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Absolute movement of the controls group |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::Move(const int x,const int y)
|
||||
{
|
||||
//--- relative movement
|
||||
return(Shift(x-Left(),y-Top()));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Absolute movement of the controls group |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::Move(const CPoint &point)
|
||||
{
|
||||
//--- relative movement
|
||||
return(Shift(point.x-Left(),point.y-Top()));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Relative movement of the controls group |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::Shift(const int dx,const int dy)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
if(!CWnd::Shift(dx,dy)) return(false);
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
//--- move the group item
|
||||
control.Shift(dx,dy);
|
||||
}
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set ID of control |
|
||||
//+------------------------------------------------------------------+
|
||||
long CWndContainer::Id(const long id)
|
||||
{
|
||||
//--- reserve ID for container
|
||||
long id_used=1;
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
id_used+=control.Id(id+id_used);
|
||||
}
|
||||
m_id=id;
|
||||
//--- return number of used IDs
|
||||
return(id_used);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Enables event handling by the group of controls |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::Enable(void)
|
||||
{
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
control.Enable();
|
||||
}
|
||||
//--- call of the method of the parent class
|
||||
return(CWnd::Enable());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Disables event handling by the group of controls |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::Disable(void)
|
||||
{
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
control.Disable();
|
||||
}
|
||||
//--- call of the method of the parent class
|
||||
return(CWnd::Disable());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Makes the group of controls visible |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::Show(void)
|
||||
{
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
control.Show();
|
||||
}
|
||||
//--- call of the method of the parent class
|
||||
return(CWnd::Show());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Makes the group of controls hidden |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::Hide(void)
|
||||
{
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
control.Hide();
|
||||
}
|
||||
//--- call of the method of the parent class
|
||||
return(CWnd::Hide());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of resizing |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::OnResize()
|
||||
{
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
if(!control.Align(Rect()))
|
||||
return(false);
|
||||
}
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of activating the group of controls |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::OnActivate(void)
|
||||
{
|
||||
if(IS_ACTIVE)
|
||||
return(false);
|
||||
Activate();
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
control.Activate();
|
||||
}
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of deactivating the group of controls |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::OnDeactivate(void)
|
||||
{
|
||||
if(!IS_ACTIVE)
|
||||
return(false);
|
||||
Deactivate();
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
control.Deactivate();
|
||||
}
|
||||
//--- handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Save |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::Save(const int file_handle)
|
||||
{
|
||||
bool result=true;
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
result&=control.Save(file_handle);
|
||||
}
|
||||
//--- result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Load |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndContainer::Load(const int file_handle)
|
||||
{
|
||||
bool result=true;
|
||||
//--- loop by elements of group
|
||||
int total=m_controls.Total();
|
||||
for(int i=0;i<total;i++)
|
||||
{
|
||||
CWnd *control=Control(i);
|
||||
//--- check of pointer
|
||||
if(control==NULL)
|
||||
continue;
|
||||
result&=control.Load(file_handle);
|
||||
}
|
||||
//--- result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,262 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| WndObj.mqh |
|
||||
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
||||
//| www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "Wnd.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CWndObj |
|
||||
//| Usage: base class to work with chart objects |
|
||||
//+------------------------------------------------------------------+
|
||||
class CWndObj : public CWnd
|
||||
{
|
||||
private:
|
||||
//--- flags of object
|
||||
bool m_undeletable; // "object is not deletable" flag
|
||||
bool m_unchangeable; // "object is not changeable" flag
|
||||
bool m_unmoveable; // "object is not movable" flag
|
||||
|
||||
protected:
|
||||
//--- parameters of the chart object
|
||||
string m_text; // object text
|
||||
color m_color; // object color
|
||||
color m_color_background; // object background color
|
||||
color m_color_border; // object border color
|
||||
string m_font; // object font
|
||||
int m_font_size; // object font size
|
||||
long m_zorder; // Z order
|
||||
|
||||
public:
|
||||
CWndObj(void);
|
||||
~CWndObj(void);
|
||||
//--- chart event handler
|
||||
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
||||
//--- set up the object
|
||||
string Text(void) const { return(m_text); }
|
||||
bool Text(const string value);
|
||||
color Color(void) const { return(m_color); }
|
||||
bool Color(const color value);
|
||||
color ColorBackground(void) const { return(m_color_background); }
|
||||
bool ColorBackground(const color value);
|
||||
color ColorBorder(void) const { return(m_color_border); }
|
||||
bool ColorBorder(const color value);
|
||||
string Font(void) const { return(m_font); }
|
||||
bool Font(const string value);
|
||||
int FontSize(void) const { return(m_font_size); }
|
||||
bool FontSize(const int value);
|
||||
long ZOrder(void) const { return(m_zorder); }
|
||||
bool ZOrder(const long value);
|
||||
|
||||
protected:
|
||||
//--- handlers of object events
|
||||
virtual bool OnObjectCreate(void);
|
||||
virtual bool OnObjectChange(void);
|
||||
virtual bool OnObjectDelete(void);
|
||||
virtual bool OnObjectDrag(void);
|
||||
//--- handlers of object settings
|
||||
virtual bool OnSetText(void) { return(true); }
|
||||
virtual bool OnSetColor(void) { return(true); }
|
||||
virtual bool OnSetColorBackground(void) { return(true); }
|
||||
virtual bool OnSetColorBorder(void) { return(true); }
|
||||
virtual bool OnSetFont(void) { return(true); }
|
||||
virtual bool OnSetFontSize(void) { return(true); }
|
||||
virtual bool OnSetZOrder(void) { return(true); }
|
||||
//--- internal event handlers
|
||||
virtual bool OnDestroy(void) { return(ObjectDelete(m_chart_id,m_name)); }
|
||||
virtual bool OnChange(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Common handler of chart events |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndObj::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
|
||||
{
|
||||
if(m_name==sparam)
|
||||
{
|
||||
//--- object name and string parameters are equal
|
||||
//--- this means that event should be handled
|
||||
switch(id)
|
||||
{
|
||||
case CHARTEVENT_OBJECT_CREATE: return(OnObjectCreate());
|
||||
case CHARTEVENT_OBJECT_CHANGE: return(OnObjectChange());
|
||||
case CHARTEVENT_OBJECT_DELETE: return(OnObjectDelete());
|
||||
case CHARTEVENT_OBJECT_DRAG : return(OnObjectDrag());
|
||||
}
|
||||
}
|
||||
//--- event was not handled
|
||||
return(CWnd::OnEvent(id,lparam,dparam,sparam));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CWndObj::CWndObj(void) : m_color(clrNONE),
|
||||
m_color_background(clrNONE),
|
||||
m_color_border(clrNONE),
|
||||
m_font(CONTROLS_FONT_NAME),
|
||||
m_font_size(CONTROLS_FONT_SIZE),
|
||||
m_zorder(0),
|
||||
m_undeletable(true),
|
||||
m_unchangeable(true),
|
||||
m_unmoveable(true)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CWndObj::~CWndObj(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set the "Text" parameter |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndObj::Text(const string value)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_text=value;
|
||||
//--- call virtual event handler
|
||||
return(OnSetText());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set the "Color" parameter |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndObj::Color(const color value)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_color=value;
|
||||
//--- call virtual event handler
|
||||
return(OnSetColor());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Setting the "Background color" parameter |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndObj::ColorBackground(const color value)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_color_background=value;
|
||||
//--- call virtual event handler
|
||||
return(OnSetColorBackground());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set the "Border color" parameter |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndObj::ColorBorder(const color value)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_color_border=value;
|
||||
//--- call virtual event handler
|
||||
return(OnSetColorBorder());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set the "Font" parameter |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndObj::Font(const string value)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_font=value;
|
||||
//--- call virtual event handler
|
||||
return(OnSetFont());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set the "Font size" parameter |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndObj::FontSize(const int value)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_font_size=value;
|
||||
//--- call virtual event handler
|
||||
return(OnSetFontSize());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set the "Z order" parameter |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndObj::ZOrder(const long value)
|
||||
{
|
||||
//--- save new value of parameter
|
||||
m_zorder=value;
|
||||
//--- call virtual event handler
|
||||
return(OnSetZOrder());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Object creation" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndObj::OnObjectCreate(void)
|
||||
{
|
||||
//--- event is handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Object modification" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndObj::OnObjectChange(void)
|
||||
{
|
||||
//--- if object is not changeable
|
||||
if(m_unchangeable)
|
||||
{
|
||||
//--- restore position
|
||||
if(!OnMove())
|
||||
return(false);
|
||||
//--- restore size
|
||||
if(!OnResize())
|
||||
return(false);
|
||||
//--- restore settings
|
||||
if(!OnChange())
|
||||
return(false);
|
||||
}
|
||||
//--- event is handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Object deletion" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndObj::OnObjectDelete(void)
|
||||
{
|
||||
//--- if object is not deletable
|
||||
if(m_undeletable)
|
||||
{
|
||||
//--- restore the object
|
||||
if(!OnCreate())
|
||||
return(false);
|
||||
//--- restore settings
|
||||
if(!OnChange())
|
||||
return(false);
|
||||
//--- restore visibility
|
||||
return(IS_VISIBLE ? OnShow():OnHide());
|
||||
}
|
||||
//--- event is handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Handler of the "Object dragging" event |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndObj::OnObjectDrag(void)
|
||||
{
|
||||
//--- if object is not movable
|
||||
if(m_unmoveable)
|
||||
{
|
||||
//--- restore position
|
||||
return(OnMove());
|
||||
}
|
||||
//--- event is handled
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set up the object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWndObj::OnChange(void)
|
||||
{
|
||||
//--- set up the chart object according to previously set parameters
|
||||
if(!OnSetText())
|
||||
return(false);
|
||||
if(!OnSetFont())
|
||||
return(false);
|
||||
if(!OnSetFontSize())
|
||||
return(false);
|
||||
if(!OnSetColor())
|
||||
return(false);
|
||||
if(!OnSetColorBackground())
|
||||
return(false);
|
||||
if(!OnSetColorBorder())
|
||||
return(false);
|
||||
//--- succeed
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
After Width: | Height: | Size: 576 B |
|
After Width: | Height: | Size: 576 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 824 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 824 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 632 B |
|
After Width: | Height: | Size: 632 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 824 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 568 B |
|
After Width: | Height: | Size: 568 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 824 B |
|
After Width: | Height: | Size: 1.1 KiB |