EasyAndFastMod/Controls/Calendar.mqh

1014 lines
80 KiB
MQL5
Raw Permalink Normal View History

2026-01-15 07:23:17 -05:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| Calendar.mqh |
//| Copyright 2015, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "..\Element.mqh"
#include "TextEdit.mqh"
#include "ComboBox.mqh"
#include "Button.mqh"
#include "ButtonsGroup.mqh"
#include <Tools\DateTime.mqh>
//--- >;8G5AB2> 4=59 2 B01;8F5
#define DAYS_TOTAL 42
//+------------------------------------------------------------------+
//| ;0AA 4;O A>740=8O :0;5=40@O |
//+------------------------------------------------------------------+
class CCalendar : public CElement
{
private:
//--- -;5<5=BK 4;O A>740=8O :0;5=40@O
CButton m_month_dec;
CButton m_month_inc;
CComboBox m_months;
CTextEdit m_years;
CButtonsGroup m_days;
CButton m_button_today;
//--- -:75?;O@K AB@C:BC@K 4;O @01>BK A 40B0<8 8 2@5<5=5<:
CDateTime m_date; // 2K45;5==0O ?>;L7>20B5;5< 40B0
CDateTime m_today; // B5:CI0O (;>:0;L=0O =0 :><?LNB5@5 ?>;L7>20B5;O) 40B0
CDateTime m_temp_date; // M:75<?;O@ 4;O @0AGQB>2 8 ?@>25@>:
//--- &25B ?C=:B0 B5:CI53> 4=O
color m_today_color;
//--- &25B @0745;8B5;L=>9 ;8=88
color m_sepline_color;
//--- !GQBG8: B09<5@0 4;O ?5@5<>B:8 A?8A:0
int m_timer_counter;
//---
public:
CCalendar(void);
~CCalendar(void);
//--- 5B>4K 4;O A>740=8O :0;5=40@O
bool CreateCalendar(const int x_gap,const int y_gap);
//---
private:
void InitializeProperties(const int x_gap,const int y_gap);
bool CreateCanvas(void);
bool CreateMonthArrow(CButton &button_obj,const int index);
bool CreateMonthsList(void);
bool CreateYearsSpinEdit(void);
bool CreateDaysMonth(void);
bool CreateButtonToday(void);
//---
public:
//--- >72@0I05B C:070B5;8 =0 M;5<5=BK :0;5=40@O
CButton *GetMonthDecPointer(void) { return(::GetPointer(m_month_dec)); }
CButton *GetMonthIncPointer(void) { return(::GetPointer(m_month_inc)); }
CComboBox *GetComboBoxPointer(void) { return(::GetPointer(m_months)); }
CTextEdit *GetSpinEditPointer(void) { return(::GetPointer(m_years)); }
CButton *GetTodayButtonPointer(void) { return(::GetPointer(m_button_today)); }
CButtonsGroup *GetDayButtonsPointer(void) { return(::GetPointer(m_days)); }
//--- (1) ?>;CG8BL B5:CICN 40BC 2 :0;5=40@5, (2) #AB0=>28BL (2K45;8BL) 8 (3) ?>;CG8BL 2K45;5==CN 40BC
datetime Today(void) { return(m_today.DateTime()); }
datetime SelectedDate(void) { return(m_date.DateTime()); }
void SelectedDate(const datetime date);
//--- B>1@065=85 ?>A;54=8E 87<5=5=89 2 :0;5=40@5
void UpdateCalendar(void);
//--- 1=>2;O5B M;5<5=BK :0;5=40@O
void UpdateElements(void);
//--- 1=>2;5=85 B5:CI59 40BK
void UpdateCurrentDate(void);
//---
public:
//--- 1@01>BG8: A>1KB89 3@0D8:0
virtual void OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- "09<5@
virtual void OnEventTimer(void);
//--- >:07
virtual void Show(void);
//--- 8AC5B M;5<5=B
virtual void Draw(void);
//---
private:
//--- 1@01>B:0 =060B8O =0 :=>?:5 ?5@5E>40 : ?@54K4CI5<C <5AOFC
bool OnClickMonthDec(const string clicked_object,const int id,const int index);
//--- 1@01>B:0 =060B8O =0 :=>?:5 ?5@5E>40 : A;54CNI5<C <5AOFC
bool OnClickMonthInc(const string clicked_object,const int id,const int index);
//--- 1@01>B:0 2K1>@0 <5AOF0 2 A?8A:5
bool OnClickMonthList(const int id);
//--- 1@01>B:0 22>40 7=0G5=8O 2 ?>;5 22>40 ;5B
bool OnEndEnterYear(const string edited_object,const int id);
//--- 1@01>B:0 =060B8O =0 :=>?:5 ?5@5E>40 : A;54CNI5<C 3>4C
bool OnClickYearInc(const string clicked_object,const int id,const int index);
//--- 1@01>B:0 =060B8O =0 :=>?:5 ?5@5E>40 : ?@54K4CI5<C 3>4C
bool OnClickYearDec(const string clicked_object,const int id,const int index);
//--- 1@01>B:0 =060B8O =0 4=5 <5AOF0
bool OnClickDayOfMonth(const string clicked_object,const int id,const int index);
//--- 1@01>B:0 =060B8O =0 :=>?:5 ?5@5E>40 : B5:CI59 40B5
bool OnClickTodayButton(const string clicked_object,const int id,const int index);
//--- >@@5:B8@>2:0 2K45;5==>3> 4=O ?> :>;8G5AB2C 4=59 2 <5AOF5
void CorrectingSelectedDay(void);
//--- ?@545;5=85 @07=8FK >B ?5@2>3> ?C=:B0 B01;8FK :0;5=40@O 4> ?C=:B0 ?5@2>3> 4=O B5:CI53> <5AOF0
int OffsetFirstDayOfMonth(void);
//--- B>1@0605B ?>A;54=85 87<5=5=8O 2 B01;8F5 :0;5=40@O
void SetCalendar(void);
//--- #A:>@5==0O ?5@5<>B:0 7=0G5=89 :0;5=40@O
void FastSwitching(void);
//--- >4A25B:0 B5:CI53> 4=O 8 2K1@0==>3> ?>;L7>20B5;5< 4=O
void HighlightDate(void);
//--- !1@>A 2@5<5=8 =0 =0G0;> ACB>:
void ResetTime(void);
//--- 8AC5B =0720=8O 4=59 =545;8
void DrawDaysWeek(void);
//--- 8AC5B @0745;8B5;L=CN ;8=8N
void DrawSeparateLine(void);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CCalendar::CCalendar(void) : m_today_color(C'0,102,204')
{
//--- !>E@0=8< 8<O :;0AA0 M;5<5=B0 2 107>2>< :;0AA5
CElementBase::ClassName(CLASS_NAME);
//--- =8F80;870F8O AB@C:BC@ 2@5<5=8
m_date.DateTime(::TimeLocal());
m_today.DateTime(::TimeLocal());
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CCalendar::~CCalendar(void)
{
}
//+------------------------------------------------------------------+
//| 1@01>BG8: A>1KB89 |
//+------------------------------------------------------------------+
void CCalendar::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
//--- 1@01>B:0 A>1KB8O 2K1>@0 ?C=:B0 2 2K?040NI5< A?8A:5
if(id==CHARTEVENT_CUSTOM+ON_CLICK_COMBOBOX_ITEM)
{
//--- 1@01>B:0 22>40 7=0G5=8O 2 ?>;5 22>40 ;5B
if(OnClickMonthList((int)lparam))
return;
//---
return;
}
//--- 1@01>B:0 A>1KB8O 22>40 7=0G5=8O 2 ?>;5 22>40
if(id==CHARTEVENT_CUSTOM+ON_END_EDIT)
{
//--- 1@01>B:0 22>40 7=0G5=8O 2 ?>;5 22>40 ;5B
if(OnEndEnterYear(sparam,(int)lparam))
return;
//---
return;
}
//--- 1@01>B:0 A>1KB8O =060B8O =0 :=>?:5 2 3@C??5
if(id==CHARTEVENT_CUSTOM+ON_CLICK_GROUP_BUTTON)
{
//--- 1@01>B:0 =060B8O =0 4=5 :0;5=40@O
if(OnClickDayOfMonth(sparam,(int)lparam,(int)dparam))
return;
//---
return;
}
//--- 1@01>B:0 A>1KB8O =060B8O =0 :=>?:5
if(id==CHARTEVENT_CUSTOM+ON_CLICK_BUTTON)
{
//--- 1@01>B:0 =060B8O =0 :=>?:0E ?5@5:;NG5=8O <5AOF52
if(OnClickMonthDec(sparam,(int)lparam,(int)dparam))
return;
if(OnClickMonthInc(sparam,(int)lparam,(int)dparam))
return;
//--- 1@01>B:0 =060B8O =0 :=>?:0E ?5@5E>40 ?> 3>40<
if(OnClickYearInc(sparam,(int)lparam,(int)dparam))
return;
if(OnClickYearDec(sparam,(int)lparam,(int)dparam))
return;
//--- 1@01>B:0 =060B8O =0 :=>?:5 ?5@5E>40 : B5:CI59 40B5
if(OnClickTodayButton(sparam,(int)lparam,(int)dparam))
return;
//---
return;
}
}
//+------------------------------------------------------------------+
//| "09<5@ |
//+------------------------------------------------------------------+
void CCalendar::OnEventTimer(void)
{
//--- #A:>@5==0O ?5@5<>B:0 7=0G5=89
FastSwitching();
//--- 1=>2;5=85 B5:CI59 40BK :0;5=40@O
UpdateCurrentDate();
}
//+------------------------------------------------------------------+
//| !>740QB :>=B5:AB=>5 <5=N |
//+------------------------------------------------------------------+
bool CCalendar::CreateCalendar(const int x_gap,const int y_gap)
{
//--- K9B8, 5A;8 =5B C:070B5;O =0 3;02=K9 M;5<5=B
if(!CElement::CheckMainPointer())
return(false);
//--- =8F80;870F8O A2>9AB2
InitializeProperties(x_gap,y_gap);
//--- !>740=85 M;5<5=B0
if(!CreateCanvas())
return(false);
if(!CreateMonthArrow(m_month_dec,0))
return(false);
if(!CreateMonthArrow(m_month_inc,1))
return(false);
if(!CreateMonthsList())
return(false);
if(!CreateYearsSpinEdit())
return(false);
if(!CreateDaysMonth())
return(false);
if(!CreateButtonToday())
return(false);
//--- 1=>28BL :0;5=40@L
UpdateCalendar();
return(true);
}
//+------------------------------------------------------------------+
//| =8F80;870F8O A2>9AB2 |
//+------------------------------------------------------------------+
void CCalendar::InitializeProperties(const int x_gap,const int y_gap)
{
m_x =CElement::CalculateX(x_gap);
m_y =CElement::CalculateY(y_gap);
m_x_size =161;
m_y_size =158;
//--- &25B0 C<>;G0=8N
m_back_color =(m_back_color!=clrNONE)? m_back_color : clrWhite;
m_border_color =(m_border_color!=clrNONE)? m_border_color : C'150,170,180';
m_label_color =(m_label_color!=clrNONE)? m_label_color : clrBlack;
m_label_color_locked =(m_label_color_locked!=clrNONE)? m_label_color_locked : C'200,200,200';
//--- BABC?K >B :@09=59 B>G:8
CElementBase::XGap(x_gap);
CElementBase::YGap(y_gap);
}
//+------------------------------------------------------------------+
//| !>740QB >1J5:B 4;O @8A>20=8O |
//+------------------------------------------------------------------+
bool CCalendar::CreateCanvas(void)
{
//--- $>@<8@>20=85 8<5=8 >1J5:B0
string name=CElementBase::ElementName("calendar");
//--- !>740=85 >1J5:B0
if(!CElement::CreateCanvas(name,m_x,m_y,m_x_size,m_y_size))
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+
//| !>740QB ?5@5:;NG0B5;L <5AOF52 2;52> |
//+------------------------------------------------------------------+
bool CCalendar::CreateMonthArrow(CButton &button_obj,const int index)
{
//--- !>E@0=8< C:070B5;L =0 3;02=K9 M;5<5=B
button_obj.MainPointer(this);
//--- 07<5@K
int x_size=12;
int y_size=18;
//--- BABC?
int offset=2;
//--- >>@48=0BK
int x =(index<1)? offset : x_size+offset;
int y =offset;
//--- !2>9AB20
button_obj.Index(index);
button_obj.XSize(x_size);
button_obj.YSize(y_size);
button_obj.IconXGap(-2);
button_obj.IconYGap(1);
button_obj.IsDropdown(CElementBase::IsDropdown());
//--- /@;K:8 4;O :=>?>:
if(index<1)
{
button_obj.IconFile(RESOURCE_LEFT_THIN_BLACK);
button_obj.IconFileLocked(RESOURCE_LEFT_THIN_BLACK);
}
else
{
button_obj.IconFile(RESOURCE_RIGHT_THIN_BLACK);
button_obj.IconFileLocked(RESOURCE_RIGHT_THIN_BLACK);
button_obj.AnchorRightWindowSide(true);
}
//--- !>74048< M;5<5=B C?@02;5=8O
if(!button_obj.CreateButton("",x,y))
return(false);
//--- >1028BL M;5<5=B 2 <0AA82
CElement::AddToArray(button_obj);
return(true);
}
//+------------------------------------------------------------------+
//| !>740QB :><1>-1>:A A <5AOF0<8 |
//+------------------------------------------------------------------+
bool CCalendar::CreateMonthsList(void)
{
//--- !>E@0=8< C:070B5;L =0 3;02=K9 M;5<5=B
m_months.MainPointer(this);
//--- >>@48=0BK
int x=14,y=2;
//--- !2>9AB20
m_months.XSize(50);
m_months.YSize(18);
m_months.ItemsTotal(12);
m_months.GetButtonPointer().XGap(1);
m_months.GetButtonPointer().LabelYGap(3);
m_months.IsDropdown(CElementBase::IsDropdown());
//--- >;CG8< C:070B5;L =0 A?8A>:
CListView *lv=m_months.GetListViewPointer();
//--- #AB0=>28< A2>9AB20 A?8A:0
lv.YSize(93);
lv.LightsHover(true);
//--- 0=5AQ< 7=0G5=8O 2 A?8A>: (=0720=8O <5AOF52)
for(int i=0; i<12; i++)
m_months.SetValue(i,m_date.MonthName(i+1));
//--- K45;8< 2 A?8A:5 B5:CI89 <5AOF
m_months.SelectItem(m_date.mon-1);
//--- !>74048< M;5<5=B C?@02;5=8O
if(!m_months.CreateComboBox("",x,y))
return(false);
//--- >1028BL M;5<5=B 2 <0AA82
CElement::AddToArray(m_months);
return(true);
}
//+------------------------------------------------------------------+
//| !>740QB ?>;5 22>40 3>40 |
//+------------------------------------------------------------------+
bool CCalendar::CreateYearsSpinEdit(void)
{
//--- !>E@0=8< C:070B5;L =0 3;02=K9 M;5<5=B
m_years.MainPointer(this);
//--- >>@48=0BK
int x=95,y=2;
//--- !2>9AB20
m_years.Index(m_is_dropdown? 1 : 0);
m_years.XSize(50);
m_years.YSize(18);
m_years.MaxValue(2099);
m_years.MinValue(1970);
m_years.StepValue(1);
m_years.SetDigits(0);
m_years.SpinEditMode(true);
m_years.GetTextBoxPointer().AutoSelectionMode(true);
m_years.SetValue((string)m_date.year);
m_years.GetTextBoxPointer().XGap(1);
m_years.GetTextBoxPointer().XSize(50);
m_years.GetIncButtonPointer().NamePart("cal_spin_inc");
m_years.GetDecButtonPointer().NamePart("cal_spin_dec");
//--- !>74048< M;5<5=B C?@02;5=8O
if(!m_years.CreateTextEdit("",x,y))
return(false);
//--- BABC? B5:AB0 2 ?>;5 22>40
m_years.GetTextBoxPointer().TextYOffset(4);
//--- >1028BL M;5<5=B 2 <0AA82
CElement::AddToArray(m_years);
return(true);
}
//+------------------------------------------------------------------+
//| !>740QB B01;8FC 4=59 <5AOF0 |
//+------------------------------------------------------------------+
bool CCalendar::CreateDaysMonth(void)
{
//--- !GQBG8: 4=59
int i=0;
//--- >>@48=0BK 8 >BABC?K
int x=0,y=0;
int x_offset=7,y_offset=44;
//--- 07<5@K
int x_size=21,y_size=15;
//--- !>E@0=8< C:070B5;L =0 3;02=K9 M;5<5=B
m_days.MainPointer(this);
//---
int buttons_x_offset[DAYS_TOTAL]={};
int buttons_y_offset[DAYS_TOTAL]={};
string buttons_text[DAYS_TOTAL]={};
//--- #AB0=>28< >1J5:BK B01;8FK 4=59 :0;5=40@O
for(int r=0; r<6; r++)
{
//--- 0AGQB :>>@48=0BK Y
y=(r>0)? y+y_size : 0;
//---
for(int c=0; c<7; c++)
{
//--- 0AGQB :>>@48=0BK X
x=(c>0)? x+x_size : 0;
//--
buttons_text[i] =string(i);
buttons_x_offset[i] =x;
buttons_y_offset[i] =y;
//---
i++;
}
}
//--- !2>9AB20
m_days.NamePart("day");
m_days.ButtonYSize(y_size);
m_days.LabelYGap(1);
m_days.IsCenterText(true);
m_days.RadioButtonsMode(true);
m_days.IsDropdown(CElementBase::IsDropdown());
//--- >1028< :=>?:8 2 3@C??C
for(int j=0; j<DAYS_TOTAL; j++)
m_days.AddButton(buttons_x_offset[j],buttons_y_offset[j],buttons_text[j],x_size);
//--- !>740BL 3@C??C :=>?>:
x=x_offset;
y=y_offset;
if(!m_days.CreateButtonsGroup(x,y))
return(false);
//--- !2>9AB20
for(int j=0; j<DAYS_TOTAL; j++)
{
m_days.GetButtonPointer(j).BackColor(m_back_color);
m_days.GetButtonPointer(j).BorderColor(m_back_color);
}
//--- >1028BL M;5<5=B 2 <0AA82
CElement::AddToArray(m_days);
return(true);
}
//+------------------------------------------------------------------+
//| !>740QB :=>?:C 4;O ?5@5E>40 =0 B5:CICN 40BC |
//+------------------------------------------------------------------+
bool CCalendar::CreateButtonToday(void)
{
//--- !>E@0=8< C:070B5;L =0 3;02=K9 M;5<5=B
m_button_today.MainPointer(this);
//--- >>@48=0BK
int x=22,y=YSize()-23;
//--- !2>9AB20
m_button_today.NamePart("today_button");
m_button_today.Index(2);
m_button_today.XSize(120);
m_button_today.YSize(20);
m_button_today.IconXGap(1);
m_button_today.IconYGap(1);
m_button_today.LabelXGap(25);
m_button_today.LabelYGap(4);
m_button_today.BackColor(m_back_color);
m_button_today.BackColorHover(m_back_color);
m_button_today.BackColorLocked(m_back_color);
m_button_today.BackColorPressed(m_back_color);
m_button_today.BorderColor(m_back_color);
m_button_today.BorderColorHover(m_back_color);
m_button_today.BorderColorLocked(m_back_color);
m_button_today.BorderColorPressed(m_back_color);
m_button_today.LabelColorHover(C'0,102,250');
m_button_today.IsDropdown(CElementBase::IsDropdown());
m_button_today.IconFile(RESOURCE_CALENDAR_TODAY);
m_button_today.IconFileLocked(RESOURCE_CALENDAR_TODAY);
m_button_today.CElement::IconFilePressed(RESOURCE_CALENDAR_TODAY);
m_button_today.CElement::IconFilePressedLocked(RESOURCE_CALENDAR_TODAY);
//--- !>74048< M;5<5=B C?@02;5=8O
if(!m_button_today.CreateButton("Today: "+::TimeToString(::TimeLocal(),TIME_DATE),x,y))
return(false);
//--- >1028BL M;5<5=B 2 <0AA82
CElement::AddToArray(m_button_today);
return(true);
}
//+------------------------------------------------------------------+
//| K1>@ =>2>9 40BK |
//+------------------------------------------------------------------+
void CCalendar::SelectedDate(const datetime date)
{
//--- !>E@0=5=85 40BK 2 AB@C:BC@5 8 ?>;5 :;0AA0
m_date.DateTime(date);
//--- B>1@065=85 ?>A;54=8E 87<5=5=89 2 :0;5=40@5
UpdateCalendar();
}
//+------------------------------------------------------------------+
//| B>1@065=85 ?>A;54=8E 87<5=5=89 2 :0;5=40@5 |
//+------------------------------------------------------------------+
void CCalendar::UpdateCalendar(void)
{
//--- B>1@078BL 87<5=5=8O 2 B01;8F5 :0;5=40@O
SetCalendar();
//--- >4A25B:0 B5:CI53> 4=O 8 2K1@0==>3> ?>;L7>20B5;5< 4=O
HighlightDate();
//--- #AB0=>28< 3>4 2 ?>;5 22>40
m_years.SetValue((string)m_date.year,false);
//--- #AB0=>28< <5AOF 2 A?8A:5 :><1>-1>:A0
m_months.SelectItem(m_date.mon-1);
}
//+------------------------------------------------------------------+
//| 1=>2;O5B M;5<5=BK :0;5=40@O |
//+------------------------------------------------------------------+
void CCalendar::UpdateElements(void)
{
m_years.GetTextBoxPointer().Update(true);
m_months.GetButtonPointer().Update(true);
m_days.Update(true);
}
//+------------------------------------------------------------------+
//| 1=>2;5=85 B5:CI59 40BK |
//+------------------------------------------------------------------+
void CCalendar::UpdateCurrentDate(void)
{
//--- !GQBG8:
static int count=0;
//--- K9B8, 5A;8 ?@>H;> <5=LH5 A5:C=4K
if(count<1000)
{
count+=TIMER_STEP_MSC;
return;
}
//--- 1=C;8BL AGQBG8:
count=0;
//--- >;CG8< B5:CI55 (;>:0;L=>5) 2@5<O
MqlDateTime local_time;
::TimeToStruct(::TimeLocal(),local_time);
//--- A;8 =0ABC?8; =>2K9 45=L
if(local_time.day!=m_today.day)
{
//--- 1=>28BL 40BC 2 :0;5=40@5
m_today.DateTime(::TimeLocal());
m_button_today.LabelText(::TimeToString(m_today.DateTime()));
//--- B>1@078BL ?>A;54=85 87<5=5=8O 2 :0;5=40@5
UpdateCalendar();
return;
}
//--- 1=>28BL 40BC 2 :0;5=40@5
m_today.DateTime(::TimeLocal());
}
//+------------------------------------------------------------------+
//| >:07K205B :0;5=40@L |
//+------------------------------------------------------------------+
void CCalendar::Show(void)
{
//--- A;8 :0;5=40@L =5 2K?040NI89, A45;0BL 2848<K<8 2A5 53> M;5<5=BK
CElement::Show();
//--- A;8 :0;5=40@L 2K?040NI89
if(CElementBase::IsDropdown())
{
int elements_total=ElementsTotal();
for(int i=0; i<elements_total; i++)
m_elements[i].Show();
}
}
//+------------------------------------------------------------------+
//| 060B85 =0 AB@5;:C 2;52>. 5@5E>4 : ?@54K4CI5<C <5AOFC. |
//+------------------------------------------------------------------+
bool CCalendar::OnClickMonthDec(const string clicked_object,const int id,const int index)
{
//--- K945<, 5A;8 =060B85 1K;> =5 =0 MB>< M;5<5=B5
if(!m_month_dec.CheckElementName(clicked_object))
return(false);
//--- K9B8, 5A;8 (1) 845=B8D8:0B>@K =5 A>2?040NB 8;8 (2) M;5<5=B 701;>:8@>20=
if(id!=CElementBase::Id() || index!=m_month_dec.Index() || CElementBase::IsLocked())
return(false);
//--- A;8 B5:CI89 3>4 2 :0;5=40@5 @025= <8=8<0;L=><C C:070==><C 8 B5:CI89 <5AOF "/=20@L"
if(m_date.year==m_years.MinValue() && m_date.mon==1)
return(true);
//--- 5@59B8 : ?@54K4CI5<C <5AOFC
m_date.MonDec();
//--- #AB0=>28BL ?5@2>5 G8A;> <5AOF0
m_date.day=1;
//--- #AB0=>28BL 2@5<O =0 =0G0;> ACB>:
ResetTime();
//--- B>1@065=85 ?>A;54=8E 87<5=5=89 2 :0;5=40@5
UpdateCalendar();
//--- 1=>2;O5B M;5<5=BK :0;5=40@O
UpdateElements();
//--- B?@028< A>>1I5=85 >1 MB><
::EventChartCustom(m_chart_id,ON_CHANGE_DATE,CElementBase::Id(),m_date.DateTime(),"");
return(true);
}
//+------------------------------------------------------------------+
//| 060B85 =0 AB@5;:C 2;52>. 5@5E>4 : A;54CNI5<C <5AOFC. |
//+------------------------------------------------------------------+
bool CCalendar::OnClickMonthInc(const string clicked_object,const int id,const int index)
{
//--- K945<, 5A;8 =060B85 1K;> =5 =0 MB>< M;5<5=B5
if(!m_month_inc.CheckElementName(clicked_object))
return(false);
//--- K9B8, 5A;8 (1) 845=B8D8:0B>@K =5 A>2?040NB 8;8 (2) M;5<5=B 701;>:8@>20=
if(id!=CElementBase::Id() || index!=m_month_inc.Index() || CElementBase::IsLocked())
return(false);
//--- A;8 B5:CI89 3>4 2 :0;5=40@5 @025= <0:A8<0;L=><C C:070==><C 8 B5:CI89 <5AOF "5:01@L"
if(m_date.year==m_years.MaxValue() && m_date.mon==12)
return(true);
//--- 5@59B8 : A;54CNI5<C <5AOFC
m_date.MonInc();
//--- #AB0=>28BL ?5@2>5 G8A;> <5AOF0
m_date.day=1;
//--- #AB0=>28BL 2@5<O =0 =0G0;> ACB>:
ResetTime();
//--- B>1@065=85 ?>A;54=8E 87<5=5=89 2 :0;5=40@5
UpdateCalendar();
//--- 1=>2;O5B M;5<5=BK :0;5=40@O
UpdateElements();
//--- B?@028< A>>1I5=85 >1 MB><
::EventChartCustom(m_chart_id,ON_CHANGE_DATE,CElementBase::Id(),m_date.DateTime(),"");
return(true);
}
//+------------------------------------------------------------------+
//| 1@01>B:0 2K1>@0 <5AOF0 2 A?8A:5 |
//+------------------------------------------------------------------+
bool CCalendar::OnClickMonthList(const int id)
{
//--- K9B8, 5A;8 845=B8D8:0B>@K M;5<5=B>2 =5 A>2?040NB
if(id!=CElementBase::Id())
return(false);
//--- >;CG8< 2K1@0==K9 <5AOF 2 A?8A:5
int month=m_months.GetListViewPointer().SelectedItemIndex()+1;
m_date.Mon(month);
//--- >@@5:B8@>2:0 2K45;5==>3> 4=O ?> :>;8G5AB2C 4=59 2 <5AOF5
CorrectingSelectedDay();
//--- #AB0=>28BL 2@5<O =0 =0G0;> ACB>:
ResetTime();
//--- B>1@078BL 87<5=5=8O 2 B01;8F5 :0;5=40@O
UpdateCalendar();
//--- 1=>2;O5B M;5<5=BK :0;5=40@O
UpdateElements();
//--- B?@028< A>>1I5=85 >1 MB><
::EventChartCustom(m_chart_id,ON_CHANGE_DATE,CElementBase::Id(),m_date.DateTime(),"");
return(true);
}
//+------------------------------------------------------------------+
//| 1@01>B:0 22>40 7=0G5=8O 2 ?>;5 22>40 ;5B |
//+------------------------------------------------------------------+
bool CCalendar::OnEndEnterYear(const string edited_object,const int id)
{
//--- K9B8, 5A;8 (1) 845=B8D8:0B>@K =5 A>2?040NB 8;8 (2) M;5<5=B 701;>:8@>20=
if(id!=CElementBase::Id() || CElementBase::IsLocked())
return(false);
//--- K945<, 5A;8 7=0G5=85 =5 87<5=8;>AL
string value=m_years.GetValue();
if(m_date.year==(int)value)
{
//--- 1=>2;O5B ?>;5 22>40
m_years.GetTextBoxPointer().Update(true);
return(false);
}
//--- !:>@@5:B8@C5< 7=0G5=85 2 A;CG05 2KE>40 70 CAB0=>2;5==K5 >3@0=8G5=8O
if((int)value<m_years.MinValue())
value=(string)int(m_years.MinValue());
if((int)value>m_years.MaxValue())
value=(string)int(m_years.MaxValue());
//--- ?@545;8< :>;8G5AB2> 4=59 2 B5:CI5< <5AOF5
string year =value;
string month =string(m_date.mon);
string day =string(1);
m_temp_date.DateTime(::StringToTime(year+"."+month+"."+day));
//--- A;8 7=0G5=85 2K45;5==>3> 4=O 1>;LH5, G5< :>;8G5AB2> 4=59 2 <5AOF5,
// CAB0=>28BL B5:CI55 :>;8G5AB2> 4=59 2 <5AOF5 2 :0G5AB25 2K45;5==>3> 4=O
if(m_date.day>m_temp_date.DaysInMonth())
m_date.day=m_temp_date.DaysInMonth();
//--- #AB0=>28< 40BC 2 AB@C:BC@C
m_date.DateTime(::StringToTime(year+"."+month+"."+string(m_date.day)));
//--- B>1@078< 87<5=5=8O 2 B01;8F5 :0;5=40@O
UpdateCalendar();
//--- 1=>2;O5B M;5<5=BK :0;5=40@O
UpdateElements();
//--- B?@028< A>>1I5=85 >1 MB><
::EventChartCustom(m_chart_id,ON_CHANGE_DATE,CElementBase::Id(),m_date.DateTime(),"");
return(true);
}
//+------------------------------------------------------------------+
//| 1@01>B:0 =060B8O =0 :=>?:5 ?5@5E>40 : A;54CNI5<C 3>4C |
//+------------------------------------------------------------------+
bool CCalendar::OnClickYearInc(const string clicked_object,const int id,const int index)
{
//--- K945<, 5A;8 =060B85 1K;> =5 =0 MB>< M;5<5=B5
if(!m_years.GetIncButtonPointer().CheckElementName(clicked_object))
return(false);
//--- A;8 A?8A>: <5AOF52 >B:@KB, 70:@>5< 53>
if(m_months.GetListViewPointer().IsVisible())
m_months.ChangeComboBoxListState();
//--- K9B8, 5A;8 845=B8D8:0B>@K M;5<5=B>2 =5 A>2?040NB
if(id!=CElementBase::Id())
return(false);
//--- A;8 3>4 <5=LH5 <0:A8<0;L=>3> C:070==>3>, C25;8G8BL 7=0G5=85 =0 >48=
if(m_date.year<m_years.MaxValue())
m_date.YearInc();
//--- >@@5:B8@>2:0 2K45;5==>3> 4=O ?> :>;8G5AB2C 4=59 2 <5AOF5
CorrectingSelectedDay();
//--- B>1@078BL 87<5=5=8O 2 B01;8F5 :0;5=40@O
UpdateCalendar();
//--- 1=>2;O5B M;5<5=BK :0;5=40@O
UpdateElements();
//--- B?@028< A>>1I5=85 >1 MB><
::EventChartCustom(m_chart_id,ON_CHANGE_DATE,CElementBase::Id(),m_date.DateTime(),"");
return(true);
}
//+------------------------------------------------------------------+
//| 1@01>B:0 =060B8O =0 :=>?:5 ?5@5E>40 : ?@54K4CI5<C 3>4C |
//+------------------------------------------------------------------+
bool CCalendar::OnClickYearDec(const string clicked_object,const int id,const int index)
{
//--- K945<, 5A;8 =060B85 1K;> =5 =0 MB>< M;5<5=B5
if(!m_years.GetDecButtonPointer().CheckElementName(clicked_object))
return(false);
//--- A;8 A?8A>: <5AOF52 >B:@KB, 70:@>5< 53>
if(m_months.GetListViewPointer().IsVisible())
m_months.ChangeComboBoxListState();
//--- K9B8, 5A;8 845=B8D8:0B>@K M;5<5=B>2 =5 A>2?040NB
if(id!=CElementBase::Id())
return(false);
//--- A;8 3>4 1>;LH5 <8=8<0;L=>3> C:070==>3>, C<5=LH8BL 7=0G5=85 =0 >48=
if(m_date.year>m_years.MinValue())
m_date.YearDec();
//--- >@@5:B8@>2:0 2K45;5==>3> 4=O ?> :>;8G5AB2C 4=59 2 <5AOF5
CorrectingSelectedDay();
//--- B>1@078BL 87<5=5=8O 2 B01;8F5 :0;5=40@O
UpdateCalendar();
//--- 1=>2;O5B M;5<5=BK :0;5=40@O
UpdateElements();
//--- B?@028< A>>1I5=85 >1 MB><
::EventChartCustom(m_chart_id,ON_CHANGE_DATE,CElementBase::Id(),m_date.DateTime(),"");
return(true);
}
//+------------------------------------------------------------------+
//| 1@01>B:0 =060B8O =0 4=5 <5AOF0 :0;5=40@O |
//+------------------------------------------------------------------+
bool CCalendar::OnClickDayOfMonth(const string clicked_object,const int id,const int index)
{
//--- K9B8, 5A;8 (1) 845=B8D8:0B>@K =5 A>2?040NB 8;8 (2) M;5<5=B 701;>:8@>20=
if(id!=CElementBase::Id() || CElementBase::IsLocked())
return(false);
//--- ?@545;5=85 @07=8FK >B ?5@2>3> ?C=:B0 B01;8FK :0;5=40@O 4> ?C=:B0 ?5@2>3> 4=O B5:CI53> <5AOF0
OffsetFirstDayOfMonth();
//--- @>94Q<AO 2 F8:;5 ?> ?C=:B0< B01;8FK :0;5=40@O
int items_total=m_days.ButtonsTotal();
for(int i=0; i<items_total; i++)
{
//--- A;8 40B0 B5:CI53> ?C=:B0 <5=LH5, G5< CAB0=>2;5==K9 2 A8AB5<5 <8=8<C<
if(m_temp_date.DateTime()<datetime(D'01.01.1970'))
{
//--- A;8 MB> >1J5:B, =0 :>B>@K9 =060;8
if(i==index)
return(false);
//--- 5@59B8 : A;54CNI59 40B5
m_temp_date.DayInc();
continue;
}
//--- A;8 MB> >1J5:B, =0 :>B>@K9 =060;8
if(i==index)
{
//--- !>E@0=8< 40BC
m_date.DateTime(m_temp_date.DateTime());
//--- B>1@065=85 ?>A;54=8E 87<5=5=89 2 :0;5=40@5
UpdateCalendar();
break;
}
//--- 5@59B8 : A;54CNI59 40B5
m_temp_date.DayInc();
//--- @>25@:0 2KE>40 70 CAB0=>2;5==K9 2 A8AB5<5 <0:A8<C<
if(m_temp_date.year>m_years.MaxValue())
return(false);
}
//--- 1=>2;O5B M;5<5=BK :0;5=40@O
UpdateElements();
//--- B?@028< A>>1I5=85 >1 MB><
::EventChartCustom(m_chart_id,ON_CHANGE_DATE,CElementBase::Id(),m_date.DateTime(),"");
return(true);
}
//+------------------------------------------------------------------+
//| 1@01>B:0 =060B8O =0 :=>?:5 ?5@5E>40 : B5:CI59 40B5 |
//+------------------------------------------------------------------+
bool CCalendar::OnClickTodayButton(const string clicked_object,const int id,const int index)
{
//--- K9B8, 5A;8 GC6>5 8<O >1J5:B0
if(::StringFind(clicked_object,m_button_today.NamePart(),0)<0)
return(false);
//--- K9B8, 5A;8 845=B8D8:0B>@K M;5<5=B>2 =5 A>2?040NB
if(id!=CElementBase::Id())
return(false);
//--- A;8 A?8A>: <5AOF52 >B:@KB, 70:@>5< 53>
if(m_months.GetListViewPointer().IsVisible())
m_months.ChangeComboBoxListState();
//--- #AB0=>28BL B5:CICN 40BC
m_date.DateTime(::TimeLocal());
//--- B>1@065=85 ?>A;54=8E 87<5=5=89 2 :0;5=40@5
UpdateCalendar();
//--- 1=>2;O5B M;5<5=BK :0;5=40@O
UpdateElements();
//--- B?@028< A>>1I5=85 >1 MB><
::EventChartCustom(m_chart_id,ON_CHANGE_DATE,CElementBase::Id(),m_date.DateTime(),"");
return(true);
}
//+------------------------------------------------------------------+
//| ?@545;5=85 ?5@2>3> 4=O <5AOF0 |
//+------------------------------------------------------------------+
void CCalendar::CorrectingSelectedDay(void)
{
//--- #AB0=>28BL B5:CI55 :>;8G5AB2> 4=59 2 <5AOF5, 5A;8 7=0G5=85 2K45;5==>3> 4=O 1>;LH5
if(m_date.day>m_date.DaysInMonth())
m_date.day=m_date.DaysInMonth();
}
//+------------------------------------------------------------------+
//| ?@545;5=85 @07=8FK >B ?5@2>3> ?C=:B0 B01;8FK :0;5=40@O |
//| 4> ?C=:B0 ?5@2>3> 4=O B5:CI53> <5AOF0 |
//+------------------------------------------------------------------+
int CCalendar::OffsetFirstDayOfMonth(void)
{
//--- >;CG8< 40BC ?5@2>3> 4=O 2K45;5==>3> 3>40 8 <5AOF0 2 2845 AB@>:8
string date=string(m_date.year)+"."+string(m_date.mon)+"."+string(1);
//--- #AB0=>28< MBC 40BC 2 AB@C:BC@C 4;O @0AGQB>2
m_temp_date.DateTime(::StringToTime(date));
//--- A;8 @57C;LB0B 2KG8B0=8O 548=8FK >B B5:CI53> =><5@0 4=O =545;8 1>;LH5 ;81> @025= =C;N,
// 25@=CBL @57C;LB0B, 8=0G5 25@=CBL 7=0G5=85 6
int diff=(m_temp_date.day_of_week-1>=0) ? m_temp_date.day_of_week-1 : 6;
//--- 0?><=8< 40BC, :>B>@0O ?@8E>48BAO =0 ?5@2K9 ?C=:B B01;8FK
m_temp_date.DayDec(diff);
return(diff);
}
//+------------------------------------------------------------------+
//| #AB0=>2:0 7=0G5=89 :0;5=40@O |
//+------------------------------------------------------------------+
void CCalendar::SetCalendar(void)
{
//--- ?@545;5=85 @07=8FK >B ?5@2>3> ?C=:B0 B01;8FK :0;5=40@O 4> ?C=:B0 ?5@2>3> 4=O B5:CI53> <5AOF0
int diff=OffsetFirstDayOfMonth();
//--- @>94Q<AO 2 F8:;5 ?> 2A5< ?C=:B0< B01;8FK :0;5=40@O
int items_total=m_days.ButtonsTotal();
for(int i=0; i<items_total; i++)
{
//--- #AB0=>2:0 4=O 2 B5:CI89 ?C=:B B01;8FK
m_days.GetButtonPointer(i).LabelText(string(m_temp_date.day));
//--- 5@59B8 : A;54CNI59 40B5
m_temp_date.DayInc();
}
}
//+------------------------------------------------------------------+
//| #A:>@5==0O ?@><>B:0 :0;5=40@O |
//+------------------------------------------------------------------+
void CCalendar::FastSwitching(void)
{
//--- K945<, 5A;8 =5B D>:CA0 =0 M;5<5=B5
if(!CElementBase::MouseFocus())
return;
//--- 5@=Q< AGQBG8: : ?5@2>=0G0;L=><C 7=0G5=8N, 5A;8 :=>?:0 <KH8 >B60B0
if(!m_mouse.LeftButtonState())
m_timer_counter=SPIN_DELAY_MSC;
//--- A;8 65 :=>?:0 <KH8 =060B0
else
{
//--- #25;8G8< AGQBG8: =0 CAB0=>2;5==K9 8=B5@20;
m_timer_counter+=TIMER_STEP_MSC;
//--- K945<, 5A;8 <5=LH5 =C;O
if(m_timer_counter<0)
return;
//--- A;8 ;520O AB@5;:0 =060B0
if(m_month_dec.MouseFocus())
{
//--- A;8 B5:CI89 3>4 2 :0;5=40@5 1>;LH5/@025= <8=8<0;L=>3> C:070==>3>
if(m_date.year>=m_years.MinValue())
{
//--- A;8 B5:CI89 3>4 2 :0;5=40@5 C65 @025= <8=8<0;L=><C C:070==><C 8
// B5:CI89 <5AOF "/=20@L"
if(m_date.year==m_years.MinValue() && m_date.mon==1)
return;
//--- 5@59B8 : A;54CNI5<C <5AOFC (2 AB>@>=C C<5=LH5=8O)
m_date.MonDec();
//--- #AB0=>28BL ?5@2>5 G8A;> <5AOF0
m_date.day=1;
}
}
//--- A;8 ?@020O AB@5;:0 =060B0
else if(m_month_inc.MouseFocus())
{
//--- A;8 B5:CI89 2 :0;5=40@5 3>4 <5=LH5/@025= <0:A8<0;L=>3> C:070==>3>
if(m_date.year<=m_years.MaxValue())
{
//--- A;8 B5:CI89 3>4 2 :0;5=40@5 C65 @025= <0:A8<0;L=><C C:070==><C 8
// B5:CI89 <5AOF "5:01@L"
if(m_date.year==m_years.MaxValue() && m_date.mon==12)
return;
//--- 5@59B8 : A;54CNI5<C <5AOFC (2 AB>@>=C C25;8G5=8O)
m_date.MonInc();
//--- #AB0=>28BL ?5@2>5 G8A;> <5AOF0
m_date.day=1;
}
}
//--- A;8 :=>?:0 8=:@5<5=B0 ?>;O 22>40 ;5B =060B0
else if(m_years.GetIncButtonPointer().MouseFocus())
{
//--- A;8 <5=LH5 <0:A8<0;L=>3> C:070==>3> 3>40,
// ?5@59B8 : A;54CNI5<C 3>4C (2 AB>@>=C C25;8G5=8O)
if(m_date.year<m_years.MaxValue())
m_date.YearInc();
else
return;
}
//--- A;8 :=>?:0 45:@5<5=B0 ?>;O 22>40 ;5B =060B0
else if(m_years.GetDecButtonPointer().MouseFocus())
{
//--- A;8 1>;LH5 <8=8<0;L=>3> C:070==>3> 3>40,
// ?5@59B8 : A;54CNI5<C 3>4C (2 AB>@>=C C<5=LH5=8O)
if(m_date.year>m_years.MinValue())
m_date.YearDec();
else
return;
}
else
return;
//--- B>1@065=85 ?>A;54=8E 87<5=5=89 2 :0;5=40@5
UpdateCalendar();
//--- 1=>2;O5B M;5<5=BK :0;5=40@O
UpdateElements();
//--- B?@028< A>>1I5=85 >1 MB><
::EventChartCustom(m_chart_id,ON_CHANGE_DATE,CElementBase::Id(),m_date.DateTime(),"");
}
}
//+------------------------------------------------------------------+
//| >4A25B:0 B5:CI53> 4=O 8 2K1@0==>3> ?>;L7>20B5;5< 4=O |
//+------------------------------------------------------------------+
void CCalendar::HighlightDate(void)
{
//--- ?@545;5=85 @07=8FK >B ?5@2>3> ?C=:B0 B01;8FK :0;5=40@O 4> ?C=:B0 ?5@2>3> 4=O B5:CI53> <5AOF0
OffsetFirstDayOfMonth();
//--- @>94Q<AO 2 F8:;5 ?> ?C=:B0< B01;8FK :0;5=40@O
int items_total=m_days.ButtonsTotal();
for(int i=0; i<items_total; i++)
{
//--- A;8 <5AOF ?C=:B0 A>2?0405B A B5:CI8< <5AOF5< 8
// 45=L ?C=:B0 A>2?0405B A 2K45;5==K< 4=Q<
if(m_temp_date.mon==m_date.mon &&
m_temp_date.day==m_date.day)
{
//--- K45;8BL MBC :=>?:C
m_days.SelectButton(i);
//--- 5@59B8 : A;54CNI5<C ?C=:BC B01;8FK
m_temp_date.DayInc();
continue;
}
//--- A;8 MB> B5:CI0O 40B0 (A53>4=O)
if(m_temp_date.year==m_today.year &&
m_temp_date.mon==m_today.mon &&
m_temp_date.day==m_today.day)
{
m_days.GetButtonPointer(i).LabelColor(m_today_color);
m_days.GetButtonPointer(i).BorderColor(m_today_color);
//--- 5@59B8 : A;54CNI5<C ?C=:BC B01;8FK
m_temp_date.DayInc();
continue;
}
//---
m_days.GetButtonPointer(i).BorderColor(m_back_color);
m_days.GetButtonPointer(i).LabelColor((m_temp_date.mon==m_date.mon)? m_label_color : m_label_color_locked);
//--- 5@59B8 : A;54CNI5<C ?C=:BC B01;8FK
m_temp_date.DayInc();
}
}
//+------------------------------------------------------------------+
//| !1@>A 2@5<5=8 =0 =0G0;> ACB>: |
//+------------------------------------------------------------------+
void CCalendar::ResetTime(void)
{
m_date.hour =0;
m_date.min =0;
m_date.sec =0;
}
//+------------------------------------------------------------------+
//| 8AC5B M;5<5=B |
//+------------------------------------------------------------------+
void CCalendar::Draw(void)
{
//--- 0@8A>20BL D>=
CElement::DrawBackground();
//--- 0@8A>20BL @0<:C
CElement::DrawBorder();
//--- 8AC5B =0720=8O 4=59 =545;8
DrawDaysWeek();
//--- 8AC5B @0745;8B5;L=CN ;8=8N
DrawSeparateLine();
}
//+------------------------------------------------------------------+
//| 8AC5B =0720=8O 4=59 =545;8 |
//+------------------------------------------------------------------+
void CCalendar::DrawDaysWeek(void)
{
//--- >>@48=0BK
int x=17,y=26;
//--- 07<5@K
int x_size =21;
int y_size =16;
//--- !GQBG8: 4=59 =545;8 (4;O <0AA820 >1J5:B>2)
int w=0;
//--- #AB0=>28< >1J5:BK >B>1@060NI85 A>:@0IQ==K5 =0720=8O 4=59 =545;8
for(int i=1; i<7; i++,w++)
{
//--- 0AGQB :>>@48=0BK X
x=(w>0)? x+x_size : x;
//--- !2>9AB20 H@8DB0
m_canvas.FontSet(CElement::Font(),-CElement::FontSize()*10,FW_NORMAL);
//--- K25AB8 B5:AB
m_canvas.TextOut(x,y,m_date.ShortDayName(i),::ColorToARGB(clrBlack),TA_CENTER);
//--- A;8 1K; A1@>A, 2K9B8
if(i==0)
break;
//--- !1@>A, 5A;8 ?@>H;8 2A5 4=8 =545;8
if(i>=6)
i=-1;
}
}
//+------------------------------------------------------------------+
//| 8AC5B @0745;8B5;L=CN ;8=8N |
//+------------------------------------------------------------------+
void CCalendar::DrawSeparateLine(void)
{
//--- >>@48=0BK
int x1=7,x2=154,y=42;
//--- 0@8A>20BL ;8=8N
m_canvas.Line(x1,y,x2,y,::ColorToARGB(m_border_color));
}
//+------------------------------------------------------------------+