327 lignes
26 Kio
MQL5
327 lignes
26 Kio
MQL5
//+------------------------------------------------------------------+
|
|
//| StatusBar.mqh |
|
|
//| Copyright 2015, MetaQuotes Software Corp. |
|
|
//| http://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#include "..\Element.mqh"
|
|
#include "TextLabel.mqh"
|
|
#include "SeparateLine.mqh"
|
|
//+------------------------------------------------------------------+
|
|
//| Класс для создания статусной строки |
|
|
//+------------------------------------------------------------------+
|
|
class CStatusBar : public CElement
|
|
{
|
|
private:
|
|
//--- Объекты для создания элемента
|
|
CTextLabel m_items[];
|
|
CSeparateLine m_sep_line[];
|
|
//---
|
|
public:
|
|
CStatusBar(void);
|
|
~CStatusBar(void);
|
|
//--- Методы для создания статусной строки
|
|
bool CreateStatusBar(const int x_gap,const int y_gap);
|
|
//---
|
|
private:
|
|
void InitializeProperties(const int x_gap,const int y_gap);
|
|
bool CreateCanvas(void);
|
|
bool CreateItems(void);
|
|
bool CreateSeparateLine(const int line_index);
|
|
//---
|
|
public:
|
|
//--- Возвращает указатель пункта и разделительной линии
|
|
CTextLabel *GetItemPointer(const uint index);
|
|
CSeparateLine *GetSeparateLinePointer(const uint index);
|
|
//--- (1) Количество пунктов и (2) разделительных линий
|
|
int ItemsTotal(void) const { return(::ArraySize(m_items)); }
|
|
int SeparateLinesTotal(void) const { return(::ArraySize(m_sep_line)); }
|
|
//--- Добавляет пункт с указанными свойствами до создания статусной строки
|
|
void AddItem(const string text,const int width);
|
|
//--- Установка значения по указанному индексу
|
|
void SetValue(const uint index,const string value);
|
|
//---
|
|
public:
|
|
//--- Удаление
|
|
virtual void Delete(void);
|
|
//--- Рисует элемент
|
|
virtual void Draw(void);
|
|
//---
|
|
private:
|
|
//--- Расчёт ширины элемента
|
|
int CalculationXSize(void);
|
|
//--- Расчёт ширины первого пункта
|
|
int CalculationFirstItemXSize(void);
|
|
//--- Расчёт X-координаты пункта
|
|
int CalculationItemX(const int item_index=0);
|
|
//--- Изменить ширину по правому краю окна
|
|
virtual void ChangeWidthByRightWindowSide(void);
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Constructor |
|
|
//+------------------------------------------------------------------+
|
|
CStatusBar::CStatusBar(void)
|
|
{
|
|
//--- Сохраним имя класса элемента в базовом классе
|
|
CElementBase::ClassName(CLASS_NAME);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Destructor |
|
|
//+------------------------------------------------------------------+
|
|
CStatusBar::~CStatusBar(void)
|
|
{
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Создаёт статусную строку |
|
|
//+------------------------------------------------------------------+
|
|
bool CStatusBar::CreateStatusBar(const int x_gap,const int y_gap)
|
|
{
|
|
//--- Выйти, если нет указателя на главный элемент
|
|
if(!CElement::CheckMainPointer())
|
|
return(false);
|
|
//--- Инициализация свойств
|
|
InitializeProperties(x_gap,y_gap);
|
|
//--- Создаёт элемент
|
|
if(!CreateCanvas())
|
|
return(false);
|
|
if(!CreateItems())
|
|
return(false);
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Инициализация свойств |
|
|
//+------------------------------------------------------------------+
|
|
void CStatusBar::InitializeProperties(const int x_gap,const int y_gap)
|
|
{
|
|
m_x =CElement::CalculateX(x_gap);
|
|
m_y =CElement::CalculateY(y_gap);
|
|
m_x_size =CalculationXSize();
|
|
m_y_size =(m_y_size<1)? 22 : m_y_size;
|
|
//--- Свойства по умолчанию
|
|
m_back_color =(m_back_color!=clrNONE)? m_back_color : C'225,225,225';
|
|
m_border_color =(m_border_color!=clrNONE)? m_border_color : m_back_color;
|
|
m_label_color =(m_label_color!=clrNONE)? m_label_color : clrBlack;
|
|
m_label_x_gap =(m_label_x_gap!=WRONG_VALUE)? m_label_x_gap : 0;
|
|
m_label_y_gap =(m_label_y_gap!=WRONG_VALUE)? m_label_y_gap : 0;
|
|
//--- Отступы от крайней точки
|
|
CElementBase::XGap(x_gap);
|
|
CElementBase::YGap(y_gap);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Создаёт объект для рисования |
|
|
//+------------------------------------------------------------------+
|
|
bool CStatusBar::CreateCanvas(void)
|
|
{
|
|
//--- Формирование имени объекта
|
|
string name=CElementBase::ElementName("statusbar");
|
|
//--- Создание объекта
|
|
if(!CElement::CreateCanvas(name,m_x,m_y,m_x_size,m_y_size))
|
|
return(false);
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Создаёт список пунктов статусной строки |
|
|
//+------------------------------------------------------------------+
|
|
bool CStatusBar::CreateItems(void)
|
|
{
|
|
int x=0,y=0;
|
|
//--- Получим количество пунктов
|
|
int items_total=ItemsTotal();
|
|
//--- Если нет ни одного пункта в группе, сообщить об этом и выйти
|
|
if(items_total<1)
|
|
{
|
|
::Print(__FUNCTION__," > Вызов этого метода нужно осуществлять, "
|
|
"когда в группе есть хотя бы один пункт! Воспользуйтесь методом CStatusBar::AddItem()");
|
|
return(false);
|
|
}
|
|
//--- Если ширина первого пункта не задана, то рассчитаем её относительно общей ширины других пунктов
|
|
if(m_items[0].XSize()<1)
|
|
m_items[0].XSize(CalculationFirstItemXSize());
|
|
//--- Создадим указанное количество пунктов
|
|
for(int i=0; i<items_total; i++)
|
|
{
|
|
//--- Сохраним указатель на родительский элемент
|
|
m_items[i].MainPointer(this);
|
|
//--- Координата X
|
|
x=(i>0)? x+m_items[i-1].XSize() : 0;
|
|
//--- Свойства
|
|
m_items[i].Index(i);
|
|
m_items[i].YSize(m_y_size);
|
|
m_items[i].Font(CElement::Font());
|
|
m_items[i].FontSize(CElement::FontSize());
|
|
m_items[i].LabelXGap(m_items[i].LabelXGap()<0? 7 : m_items[i].LabelXGap());
|
|
m_items[i].LabelYGap(m_items[i].LabelYGap()<0? 5 : m_items[i].LabelYGap());
|
|
//--- Создание объекта
|
|
if(!m_items[i].CreateTextLabel(m_items[i].LabelText(),x,y))
|
|
return(false);
|
|
//--- Добавить элемент в массив
|
|
CElement::AddToArray(m_items[i]);
|
|
}
|
|
//--- Создание разделительных линий
|
|
for(int i=1; i<items_total; i++)
|
|
CreateSeparateLine(i);
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Создаёт разделительную линию |
|
|
//+------------------------------------------------------------------+
|
|
bool CStatusBar::CreateSeparateLine(const int line_index)
|
|
{
|
|
//--- Линии устанавливаются со второго (1) пункта
|
|
if(line_index<1)
|
|
return(false);
|
|
//--- Координаты
|
|
int x =m_items[line_index].XGap();
|
|
int y =3;
|
|
//--- Корректировка индекса
|
|
int i=line_index-1;
|
|
//--- Увеличение массива линий на один элемент
|
|
int array_size=::ArraySize(m_sep_line);
|
|
::ArrayResize(m_sep_line,array_size+1);
|
|
//--- Сохраним указатель формы
|
|
m_sep_line[i].MainPointer(this);
|
|
//--- Свойства
|
|
m_sep_line[i].Index(i);
|
|
m_sep_line[i].TypeSepLine(V_SEP_LINE);
|
|
//--- Создание линии
|
|
if(!m_sep_line[i].CreateSeparateLine(x,y,2,m_y_size-6))
|
|
return(false);
|
|
//--- Добавить элемент в массив
|
|
CElement::AddToArray(m_sep_line[i]);
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает указатель пункта меню по индексу |
|
|
//+------------------------------------------------------------------+
|
|
CTextLabel *CStatusBar::GetItemPointer(const uint index)
|
|
{
|
|
uint array_size=::ArraySize(m_items);
|
|
//--- Если нет ни одного пункта в контекстном меню, сообщить об этом
|
|
if(array_size<1)
|
|
::Print(__FUNCTION__," > Вызов этого метода нужно осуществлять, когда есть хотя бы один пункт!");
|
|
//--- Корректировка в случае выхода из диапазона
|
|
uint i=(index>=array_size)? array_size-1 : index;
|
|
//--- Вернуть указатель
|
|
return(::GetPointer(m_items[i]));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает указатель разделительную линию по индексу |
|
|
//+------------------------------------------------------------------+
|
|
CSeparateLine *CStatusBar::GetSeparateLinePointer(const uint index)
|
|
{
|
|
uint array_size=::ArraySize(m_sep_line);
|
|
//--- Если нет ни одного пункта в контекстном меню, сообщить об этом
|
|
if(array_size<1)
|
|
return(NULL);
|
|
//--- Корректировка в случае выхода из диапазона
|
|
uint i=(index>=array_size)? array_size-1 : index;
|
|
//--- Вернуть указатель
|
|
return(::GetPointer(m_sep_line[i]));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Добавляет пункт меню |
|
|
//+------------------------------------------------------------------+
|
|
void CStatusBar::AddItem(const string text,const int width)
|
|
{
|
|
//--- Увеличим размер массивов на один элемент
|
|
int array_size=::ArraySize(m_items);
|
|
::ArrayResize(m_items,array_size+1);
|
|
//--- Сохраним значения переданных параметров
|
|
m_items[array_size].XSize(width);
|
|
m_items[array_size].LabelText(text);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Устанавливает значение по указанному индексу |
|
|
//+------------------------------------------------------------------+
|
|
void CStatusBar::SetValue(const uint index,const string value)
|
|
{
|
|
//--- Проверка на выход из диапазона
|
|
uint array_size=::ArraySize(m_items);
|
|
if(array_size<1)
|
|
return;
|
|
//--- Скорректировать значение индекса, если выходит из диапазона
|
|
uint correct_index=(index>=array_size)? array_size-1 : index;
|
|
//--- Установка переданного текста
|
|
m_items[correct_index].LabelText(value);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Удаление |
|
|
//+------------------------------------------------------------------+
|
|
void CStatusBar::Delete(void)
|
|
{
|
|
CElement::Delete();
|
|
//--- Освобождение массивов элемента
|
|
::ArrayFree(m_items);
|
|
::ArrayFree(m_sep_line);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Расчёт ширины элемента |
|
|
//+------------------------------------------------------------------+
|
|
int CStatusBar::CalculationXSize(void)
|
|
{
|
|
return((m_x_size<1 || m_auto_xresize_mode)? m_main.X2()-m_x-m_auto_xresize_right_offset : m_x_size);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Расчёт ширины первого пункта |
|
|
//+------------------------------------------------------------------+
|
|
int CStatusBar::CalculationFirstItemXSize(void)
|
|
{
|
|
int width=0;
|
|
//--- Получим количество пунктов
|
|
int items_total=ItemsTotal();
|
|
if(items_total<1)
|
|
return(0);
|
|
//--- Рассчитаем ширину относительно общей ширины остальных пунктов
|
|
for(int i=1; i<items_total; i++)
|
|
width+=m_items[i].XSize();
|
|
//---
|
|
return(m_x_size-width);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Изменить ширину по правому краю формы |
|
|
//+------------------------------------------------------------------+
|
|
void CStatusBar::ChangeWidthByRightWindowSide(void)
|
|
{
|
|
//--- Выйти, если включен режим фиксации к правому краю формы
|
|
if(m_anchor_right_window_side)
|
|
return;
|
|
//--- Координаты и ширина
|
|
int x=0;
|
|
//--- Рассчитаем и установим новый общий размер
|
|
int 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);
|
|
//--- Рассчитаем и установим новый размер первому пункту
|
|
x_size=CalculationFirstItemXSize();
|
|
m_items[0].XSize(x_size);
|
|
m_items[0].CanvasPointer().XSize(x_size);
|
|
m_items[0].CanvasPointer().Resize(x_size,m_y_size);
|
|
m_items[0].Update(true);
|
|
//--- Получим количество пунктов
|
|
int items_total=ItemsTotal();
|
|
//--- Установим координату и отступ для всех пунктов кроме первого
|
|
for(int i=1; i<items_total; i++)
|
|
{
|
|
x=x+m_items[i-1].XSize();
|
|
m_items[i].XGap(x);
|
|
m_sep_line[i-1].XGap(x);
|
|
m_items[i].CanvasPointer().XGap(x);
|
|
m_sep_line[i-1].CanvasPointer().XGap(x);
|
|
}
|
|
//--- Перерисовать элемент
|
|
Draw();
|
|
//--- Обновить положение объектов
|
|
Moving();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует элемент |
|
|
//+------------------------------------------------------------------+
|
|
void CStatusBar::Draw(void)
|
|
{
|
|
//--- Нарисовать фон
|
|
CElement::DrawBackground();
|
|
}
|
|
//+------------------------------------------------------------------+
|