265 lines
9.8 KiB
MQL5
265 lines
9.8 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| SpinEdit.mqh |
| |||
//| Copyright 2000-2025, MetaQuotes Ltd. |
| |||
//| https://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);
| |||
}
| |||
//+------------------------------------------------------------------+
|