212 lines
16 KiB
MQL5
212 lines
16 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| ElDropDownList.mqh |
|
|
//| Copyright 2015, Vasiliy Sokolov. |
|
|
//| http://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2015, Vasiliy Sokolov."
|
|
#property link "http://www.mql5.com"
|
|
|
|
#include <Object.mqh>
|
|
#include <Arrays\ArrayObj.mqh>
|
|
#include "..\Dictionary.mqh"
|
|
#include "Node.mqh"
|
|
#include "ElChart.mqh"
|
|
#include "ElButton.mqh"
|
|
#include "Events\Event.mqh"
|
|
#include "Events\EventChartObjClick.mqh"
|
|
#include "Events\EventChartMouseMove.mqh"
|
|
|
|
#define UP_ARROW CharToString(0x35)
|
|
#define DN_ARROW CharToString(0x36)
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
class CMenu : public CObject
|
|
{
|
|
public:
|
|
string Text;
|
|
CMenu(string text){Text=text;}
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Графический элемент "раскрывающийся список" |
|
|
//+------------------------------------------------------------------+
|
|
class CElDropDownList : public CElChart
|
|
{
|
|
private:
|
|
CElButton m_btn_list; // Кнопка, раскрывающая список
|
|
CElChart m_fon; // Фон раскрытого списка
|
|
CDictionary m_list; // Список элементов
|
|
CElChart* m_selected; // Выделенный элемент
|
|
void Showed(bool showed);
|
|
void OnObjClick(CEventChartObjClick *objClick);
|
|
void OnMouseMove(CEventChartMouseMove *mouseMove);
|
|
protected:
|
|
virtual void OnXCoordChange(void);
|
|
virtual void OnYCoordChange(void);
|
|
virtual void OnWidthChange(void);
|
|
virtual void OnHeightChange(void);
|
|
public:
|
|
CElDropDownList(void);
|
|
void AddElement(string text);
|
|
void SelectElementByName(string name);
|
|
virtual void Event(CEvent *event);
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Позиционирует объект при создании |
|
|
//+------------------------------------------------------------------+
|
|
CElDropDownList::CElDropDownList(void) : CElChart(OBJ_EDIT),m_fon(OBJ_RECTANGLE_LABEL)
|
|
{
|
|
m_btn_list.BorderType(BORDER_RAISED);
|
|
m_btn_list.BackgroundColor(clrWhiteSmoke);
|
|
m_btn_list.TextFont("Webdings");
|
|
m_btn_list.TextSize(9);
|
|
m_btn_list.Text(CharToString(0x36));
|
|
m_elements.Add(GetPointer(m_btn_list));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Добавляет новый элемент меню. |
|
|
//+------------------------------------------------------------------+
|
|
void CElDropDownList::AddElement(string text)
|
|
{
|
|
if(m_list.ContainsKey(text))return;
|
|
CElChart *elMenu=new CElChart(OBJ_EDIT);
|
|
elMenu.XCoord(XCoord()+1);
|
|
elMenu.YCoord(m_fon.YCoord()+20*m_list.Total()+1);
|
|
elMenu.Height(20);
|
|
elMenu.Width(Width()-2);
|
|
elMenu.Text(text);
|
|
elMenu.BorderColor(elMenu.BackgroundColor());
|
|
m_list.AddObject(elMenu.Name(), elMenu);
|
|
m_fon.Height(20*m_list.Total()+2);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Выделяет элемент по имени name |
|
|
//+------------------------------------------------------------------+
|
|
void CElDropDownList::SelectElementByName(string name)
|
|
{
|
|
FOREACH_DICT(m_list)
|
|
{
|
|
CElChart* elMenu = node;
|
|
if(elMenu.Text() == name)
|
|
{
|
|
m_selected=elMenu;
|
|
Text(m_selected.Text());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Перехватываем события и реагируем на них. |
|
|
//+------------------------------------------------------------------+
|
|
void CElDropDownList::Event(CEvent *event)
|
|
{
|
|
CNode::Event(event);
|
|
if(event.EventType()==EVENT_CHART_OBJECT_CLICK)
|
|
OnObjClick(event);
|
|
if(event.EventType()==EVENT_CHART_MOUSE_MOVE)
|
|
OnMouseMove(event);
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обрабатывает шелчок кнопки мыши |
|
|
//+------------------------------------------------------------------+
|
|
void CElDropDownList::OnObjClick(CEventChartObjClick *objClick)
|
|
{
|
|
if(m_list.ContainsKey(objClick.ObjectName()))
|
|
{
|
|
m_btn_list.Text(DN_ARROW);
|
|
m_btn_list.State(PUSH_OFF);
|
|
Showed(false);
|
|
m_selected=m_list.GetObjectByKey(objClick.ObjectName());
|
|
Text(m_selected.Text());
|
|
EventChartCustom(ChartID(),EVENT_CHART_LIST_CHANGED,0.0,0.0,Name());
|
|
return;
|
|
}
|
|
if(objClick.ObjectName() != m_btn_list.Name())return;
|
|
if(m_btn_list.State()==PUSH_ON)
|
|
{
|
|
m_btn_list.Text(UP_ARROW);
|
|
Showed(true);
|
|
}
|
|
else
|
|
{
|
|
m_btn_list.Text(DN_ARROW);
|
|
Showed(false);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обрабатывает движение мыши |
|
|
//+------------------------------------------------------------------+
|
|
void CElDropDownList::OnMouseMove(CEventChartMouseMove *mouseMove)
|
|
{
|
|
if(!m_fon.IsShowed())return;
|
|
//Определяем, находится ли указатель мыши в области списка элементов
|
|
bool isX=mouseMove.XCoord()>=m_fon.XCoord() &&
|
|
mouseMove.XCoord()<=m_fon.XCoord()+m_fon.Width();
|
|
bool isY=mouseMove.YCoord()>=m_fon.YCoord() &&
|
|
mouseMove.YCoord()<=m_fon.YCoord()+m_fon.Height();
|
|
bool isMain=isX && isY;
|
|
if(!isMain)return;
|
|
//Если находится, высчитываем строку, которую необходимо подсветить
|
|
long pips = mouseMove.YCoord() - m_fon.YCoord();
|
|
int index = (int)MathFloor(pips/20.0);
|
|
if(m_list.Total() <= index)return;
|
|
int i=0;
|
|
for(CElChart *node=m_list.GetFirstNode(); node!=NULL; node=m_list.GetNextNode(),i++)
|
|
{
|
|
if(i==index)
|
|
node.BackgroundColor(clrWhiteSmoke);
|
|
else
|
|
node.BackgroundColor(clrWhite);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Отображает все pop up элементы |
|
|
//+------------------------------------------------------------------+
|
|
void CElDropDownList::Showed(bool showed)
|
|
{
|
|
if(showed)
|
|
m_fon.Show();
|
|
else
|
|
m_fon.Hide();
|
|
FOREACH_DICT(m_list)
|
|
{
|
|
CElChart *el=node;
|
|
if(showed)
|
|
el.Show();
|
|
else
|
|
el.Hide();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Вслед за изменением привязки х, меняем дочернии элементы |
|
|
//+------------------------------------------------------------------+
|
|
void CElDropDownList::OnXCoordChange(void)
|
|
{
|
|
m_btn_list.XCoord(XCoord()+Width()-18);
|
|
m_fon.XCoord(XCoord());
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CElDropDownList::OnYCoordChange(void)
|
|
{
|
|
m_btn_list.YCoord(YCoord()+2);
|
|
m_fon.YCoord(YCoord()+Height()+1);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CElDropDownList::OnHeightChange(void)
|
|
{
|
|
m_btn_list.Height(Height()-4);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CElDropDownList::OnWidthChange(void)
|
|
{
|
|
m_btn_list.Width(Height()-4);
|
|
m_fon.Width(Width());
|
|
}
|
|
//+------------------------------------------------------------------+
|