EasyAndFastMod/Controls/ProgressBar.mqh
2026-01-15 07:23:17 -05:00

264 lines
22 KiB
MQL5

//+------------------------------------------------------------------+
//| ProgressBar.mqh |
//| Copyright 2015, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "..\Element.mqh"
//+------------------------------------------------------------------+
//| Класс для создания индикатора выполнения |
//+------------------------------------------------------------------+
class CProgressBar : public CElement
{
private:
//--- Цвета фона прогресс-бара и рамки фона
color m_bar_back_color;
//--- Размеры прогресс-бара
int m_bar_x_size;
int m_bar_y_size;
//--- Смещение прогресс-бара по двум осям
int m_bar_x_gap;
int m_bar_y_gap;
//--- Толщина рамки прогресс-бара
int m_bar_border_width;
//--- Цвет индикатора
color m_indicator_color;
//--- Смещение метки показателя процентов
int m_percent_x_gap;
int m_percent_y_gap;
//--- Количество знаков после запятой
int m_digits;
//--- Количество шагов диапазона
double m_steps_total;
//--- Текущая позиция индикатора
double m_current_index;
//---
public:
CProgressBar(void);
~CProgressBar(void);
//--- Методы для создания элемента
bool CreateProgressBar(const string text,const int x_gap,const int y_gap);
//---
private:
void InitializeProperties(const string text,const int x_gap,const int y_gap);
bool CreateCanvas(void);
//---
public:
//--- Цвет (1) фона и (2) рамки прогресс-бара, (3) цвет индикатора
void IndicatorBackColor(const color clr) { m_bar_back_color=clr; }
void IndicatorColor(const color clr) { m_indicator_color=clr; }
//--- (1) Толщина рамки, (2) Y-размер области индикатора
void BarBorderWidth(const int width) { m_bar_border_width=width; }
void BarYSize(const int y_size) { m_bar_y_size=y_size; }
//--- (1) Смещение прогресс бара по двум осям, (2) смещение метки показателя процентов
void BarXGap(const int x_gap) { m_bar_x_gap=x_gap; }
void BarYGap(const int y_gap) { m_bar_y_gap=y_gap; }
//--- (1) Смещение текстовой метки (процента процесса), (2) количество знаков после запятой
void PercentXGap(const int x_gap) { m_percent_x_gap=x_gap; }
void PercentYGap(const int y_gap) { m_percent_y_gap=y_gap; }
void SetDigits(const int digits) { m_digits=::fabs(digits); }
//--- Обновление индикатора по указанным значениям
void Update(const int index,const int total);
//--- Рисует элемент
virtual void Draw(void);
//---
private:
//--- Рисует индикатор
void DrawIndicator(void);
//--- Рисует процентное отображение прогресса
void DrawPercent(void);
//--- Установка новых значений для индикатора
void CurrentIndex(const int index);
void StepsTotal(const int total);
//--- Изменить ширину по правому краю окна
virtual void ChangeWidthByRightWindowSide(void);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CProgressBar::CProgressBar(void) : m_digits(0),
m_steps_total(1),
m_current_index(0),
m_bar_x_gap(0),
m_bar_y_gap(0),
m_bar_border_width(0),
m_percent_x_gap(7),
m_percent_y_gap(0),
m_bar_back_color(C'225,225,225'),
m_indicator_color(clrMediumSeaGreen)
{
//--- Сохраним имя класса элемента в базовом классе
CElementBase::ClassName(CLASS_NAME);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CProgressBar::~CProgressBar(void)
{
}
//+------------------------------------------------------------------+
//| Создаёт элемент "Индикатор прогресса" |
//+------------------------------------------------------------------+
bool CProgressBar::CreateProgressBar(const string text,const int x_gap,const int y_gap)
{
//--- Выйти, если нет указателя на главный элемент
if(!CElement::CheckMainPointer())
return(false);
//--- Инициализация свойств
InitializeProperties(text,x_gap,y_gap);
//--- Создание элемента
if(!CreateCanvas())
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+
//| Инициализация свойств |
//+------------------------------------------------------------------+
void CProgressBar::InitializeProperties(const string text,const int x_gap,const int y_gap)
{
m_x =CElement::CalculateX(x_gap);
m_y =CElement::CalculateY(y_gap);
m_label_text =text;
m_x_size =(m_x_size<1 || m_auto_xresize_mode)? m_main.X2()-m_x-m_auto_xresize_right_offset : m_x_size;
//--- Свойства по умолчанию
m_back_color =(m_back_color!=clrNONE)? m_back_color : m_main.BackColor();
m_label_color =(m_label_color!=clrNONE)? m_label_color : clrBlack;
m_label_y_gap =(m_label_y_gap!=WRONG_VALUE)? m_label_y_gap : 0;
//--- Отступы от крайней точки
CElementBase::XGap(x_gap);
CElementBase::YGap(y_gap);
}
//+------------------------------------------------------------------+
//| Создаёт объект для рисования |
//+------------------------------------------------------------------+
bool CProgressBar::CreateCanvas(void)
{
//--- Формирование имени объекта
string name=CElementBase::ElementName("progress");
//--- Создание объекта
if(!CElement::CreateCanvas(name,m_x,m_y,m_x_size,m_y_size))
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+
//| Обновляет прогресс бар |
//+------------------------------------------------------------------+
void CProgressBar::Update(const int index,const int total)
{
//--- Установить новый индекс
CurrentIndex(index);
//--- Установить новый диапазон
StepsTotal(total);
//--- Перерисовать элемент
CElement::Update(true);
}
//+------------------------------------------------------------------+
//| Рисует элемент |
//+------------------------------------------------------------------+
void CProgressBar::Draw(void)
{
//--- Нарисовать фон
CElement::DrawBackground();
//--- Нарисовать картинку
CElement::DrawImage();
//--- Нарисовать индикатор
DrawIndicator();
//--- Нарисовать рамку, если цвет указан
if(m_border_color!=clrNONE)
CElement::DrawBorder();
//--- Нарисовать текст
CElement::DrawText();
//--- Нарисовать прогресс в процентном выражении
DrawPercent();
}
//+------------------------------------------------------------------+
//| Рисует индикатор |
//+------------------------------------------------------------------+
void CProgressBar::DrawIndicator(void)
{
int x1 =m_bar_x_gap;
int y1 =m_bar_y_gap;
int x2 =m_x_size; // -40
int y2 =m_bar_y_gap+m_bar_y_size;
//--- Размер фона индикатора
m_bar_x_size=x2-m_bar_x_gap;
//--- Нарисовать фон индикатора
m_canvas.FillRectangle(x1,y1,x2,y2,::ColorToARGB(m_bar_back_color));
//--- Рассчитаем ширину индикатора
double new_width=(m_current_index/m_steps_total)*m_bar_x_size;
//--- Скорректировать, если меньше 1
if((int)new_width<1)
new_width=1;
else
{
//--- Скорректировать с учётом ширины рамки
int x_size=m_bar_x_size-(m_bar_border_width*2);
//--- Скорректировать, если выход за границу
if((int)new_width>=x_size)
new_width=x_size;
}
//--- Установим индикатору новую ширину
x1 =x1+m_bar_border_width;
y1 =y1+m_bar_border_width;
x2 =x1+(int)new_width;
y2 =y2-m_bar_border_width;
//--- Нарисовать индикатор
m_canvas.FillRectangle(x1,y1,x2,y2,::ColorToARGB(m_indicator_color));
}
//+------------------------------------------------------------------+
//| Рисует процентное отображение прогресса |
//+------------------------------------------------------------------+
void CProgressBar::DrawPercent(void)
{
int x =m_x_size-m_percent_x_gap;
int y =m_percent_y_gap;
//--- Рассчитаем процент и сформируем строку
double percent =m_current_index/m_steps_total*100;
string text =::DoubleToString((percent>100)? 100 : percent,m_digits)+"%";
//--- Нарисовать текст
m_canvas.TextOut(x,y,text,::ColorToARGB(m_label_color),TA_RIGHT);
}
//+------------------------------------------------------------------+
//| Количество шагов прогресс бара |
//+------------------------------------------------------------------+
void CProgressBar::StepsTotal(const int total)
{
//--- Скорректировать, если меньше 0
m_steps_total=(total<1)? 1 : total;
//--- Скорректировать индекс, если выход из диапазона
if(m_current_index>m_steps_total)
m_current_index=m_steps_total;
}
//+------------------------------------------------------------------+
//| Текущая позиция индикатора |
//+------------------------------------------------------------------+
void CProgressBar::CurrentIndex(const int index)
{
//--- Скорректировать, если меньше 0
if(index<0)
m_current_index=1;
//--- Скорректировать индекс, если выход из диапазона
else
m_current_index=(index>m_steps_total)? m_steps_total : index;
}
//+------------------------------------------------------------------+
//| Изменить ширину по правому краю формы |
//+------------------------------------------------------------------+
void CProgressBar::ChangeWidthByRightWindowSide(void)
{
//--- Размеры
int x_size=0;
//--- Рассчитать и установить новый размер фону элемента
x_size=m_main.X2()-m_canvas.X()-m_auto_xresize_right_offset;
CElementBase::XSize(x_size);
m_canvas.XSize(x_size);
m_canvas.Resize(x_size,m_y_size);
//--- Перерисовать элемент
CElementBase::Update(true);
//--- Обновить положение объектов
Moving();
}
//+------------------------------------------------------------------+