//+------------------------------------------------------------------+ //| DateDropList.mqh | //| Copyright 2000-2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include "WndContainer.mqh" #include "BmpButton.mqh" #include "Picture.mqh" #include #include //+------------------------------------------------------------------+ //| 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) { 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