324 lines
13 KiB
MQL5
324 lines
13 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| ComboBox.mqh |
| |||
//| Copyright 2000-2025, MetaQuotes Ltd. |
| |||
//| https://www.mql5.com |
| |||
//+------------------------------------------------------------------+
| |||
#include "WndContainer.mqh"
| |||
#include "Edit.mqh"
| |||
#include "BmpButton.mqh"
| |||
#include "ListView.mqh"
| |||
//+------------------------------------------------------------------+
| |||
//| Resources |
| |||
//+------------------------------------------------------------------+
| |||
//--- Can not place the same file into resource twice
| |||
#resource "res\\DropOn.bmp" // image file
| |||
#resource "res\\DropOff.bmp" // image file
| |||
//+------------------------------------------------------------------+
| |||
//| Class CComboBox |
| |||
//| Usage: drop-down list |
| |||
//+------------------------------------------------------------------+
| |||
class CComboBox : public CWndContainer
| |||
{
| |||
private:
| |||
//--- dependent controls
| |||
CEdit m_edit; // the entry field object
| |||
CBmpButton m_drop; // the button object
| |||
CListView m_list; // the drop-down list object
| |||
//--- set up
| |||
int m_item_height; // height of visible row
| |||
int m_view_items; // number of visible rows in the drop-down list
| |||
| |||
public:
| |||
CComboBox(void);
| |||
~CComboBox(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);
| |||
//--- fill
| |||
bool AddItem(const string item,const long value=0);
| |||
//--- set up
| |||
void ListViewItems(const int value) { m_view_items=value; }
| |||
//--- data
| |||
virtual bool ItemAdd(const string item,const long value=0) { return(m_list.ItemAdd(item,value)); }
| |||
virtual bool ItemInsert(const int index,const string item,const long value=0) { return(m_list.ItemInsert(index,item,value)); }
| |||
virtual bool ItemUpdate(const int index,const string item,const long value=0) { return(m_list.ItemUpdate(index,item,value)); }
| |||
virtual bool ItemDelete(const int index) { return(m_list.ItemDelete(index)); }
| |||
virtual bool ItemsClear(void) { return(m_list.ItemsClear()); }
| |||
//--- data
| |||
string Select(void) { return(m_edit.Text()); }
| |||
bool Select(const int index);
| |||
bool SelectByText(const string text);
| |||
bool SelectByValue(const long value);
| |||
//--- data (read only)
| |||
long Value(void) { return(m_list.Value()); }
| |||
//--- state
| |||
virtual bool Show(void);
| |||
//--- methods for working with files
| |||
virtual bool Save(const int file_handle);
| |||
virtual bool Load(const int file_handle);
| |||
| |||
protected:
| |||
//--- create dependent controls
| |||
virtual bool CreateEdit(void);
| |||
virtual bool CreateButton(void);
| |||
virtual bool CreateList(void);
| |||
//--- handlers of the dependent controls events
| |||
virtual bool OnClickEdit(void);
| |||
virtual bool OnClickButton(void);
| |||
virtual bool OnChangeList(void);
| |||
//--- show drop-down list
| |||
bool ListShow(void);
| |||
bool ListHide(void);
| |||
void CheckListHide(const int id,int x,int y);
| |||
};
| |||
//+------------------------------------------------------------------+
| |||
//| Common handler of chart events |
| |||
//+------------------------------------------------------------------+
| |||
EVENT_MAP_BEGIN(CComboBox)
| |||
ON_EVENT(ON_CLICK,m_edit,OnClickEdit)
| |||
ON_EVENT(ON_CLICK,m_drop,OnClickButton)
| |||
ON_EVENT(ON_CHANGE,m_list,OnChangeList)
| |||
CheckListHide(id,(int)lparam,(int)dparam);
| |||
//+------------------------------------------------------------------+
| |||
//| |
| |||
//+------------------------------------------------------------------+
| |||
EVENT_MAP_END(CWndContainer)
| |||
//+------------------------------------------------------------------+
| |||
//| Constructor |
| |||
//+------------------------------------------------------------------+
| |||
CComboBox::CComboBox(void) : m_item_height(CONTROLS_COMBO_ITEM_HEIGHT),
| |||
m_view_items(CONTROLS_COMBO_ITEMS_VIEW)
| |||
| |||
{
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Destructor |
| |||
//+------------------------------------------------------------------+
| |||
CComboBox::~CComboBox(void)
| |||
{
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Create a control |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
| |||
{
| |||
//--- check height
| |||
if(y2-y1<CONTROLS_COMBO_MIN_HEIGHT)
| |||
return(false);
| |||
//--- call method of the parent class
| |||
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
| |||
return(false);
| |||
//--- create dependent controls
| |||
if(!CreateEdit())
| |||
return(false);
| |||
if(!CreateButton())
| |||
return(false);
| |||
if(!CreateList())
| |||
return(false);
| |||
//--- succeeded
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Create main entry field |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::CreateEdit(void)
| |||
{
| |||
//--- create
| |||
if(!m_edit.Create(m_chart_id,m_name+"Edit",m_subwin,0,0,Width(),Height()))
| |||
return(false);
| |||
if(!m_edit.Text(""))
| |||
return(false);
| |||
if(!m_edit.ReadOnly(true))
| |||
return(false);
| |||
if(!Add(m_edit))
| |||
return(false);
| |||
//--- succeeded
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Create button |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::CreateButton(void)
| |||
{
| |||
//--- right align button (try to make equal offsets from top and bottom)
| |||
int x1=Width()-(CONTROLS_BUTTON_SIZE+CONTROLS_COMBO_BUTTON_X_OFF);
| |||
int y1=(Height()-CONTROLS_BUTTON_SIZE)/2;
| |||
int x2=x1+CONTROLS_BUTTON_SIZE;
| |||
int y2=y1+CONTROLS_BUTTON_SIZE;
| |||
//--- create
| |||
if(!m_drop.Create(m_chart_id,m_name+"Drop",m_subwin,x1,y1,x2,y2))
| |||
return(false);
| |||
if(!m_drop.BmpNames("::res\\DropOff.bmp","::res\\DropOn.bmp"))
| |||
return(false);
| |||
if(!Add(m_drop))
| |||
return(false);
| |||
m_drop.Locking(true);
| |||
//--- succeeded
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Create drop-down list |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::CreateList(void)
| |||
{
| |||
//--- create
| |||
if(m_list.TotalView(m_view_items))
| |||
{
| |||
if(!m_list.Create(m_chart_id,m_name+"List",m_subwin,0,Height(),Width(),0))
| |||
return(false);
| |||
if(!Add(m_list))
| |||
return(false);
| |||
m_list.Hide();
| |||
}
| |||
//--- succeeded
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Add item (row) |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::AddItem(const string item,const long value)
| |||
{
| |||
//--- add item to list
| |||
return(m_list.AddItem(item,value));
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Select item |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::Select(const int index)
| |||
{
| |||
if(!m_list.Select(index))
| |||
return(false);
| |||
//--- call the handler
| |||
return(OnChangeList());
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Select item (by text) |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::SelectByText(const string text)
| |||
{
| |||
if(!m_list.SelectByText(text))
| |||
return(false);
| |||
//--- call the handler
| |||
return(OnChangeList());
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Select item (by value) |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::SelectByValue(const long value)
| |||
{
| |||
if(!m_list.SelectByValue(value))
| |||
return(false);
| |||
//--- call the handler
| |||
return(OnChangeList());
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Makes the control visible |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::Show(void)
| |||
{
| |||
m_edit.Show();
| |||
m_drop.Show();
| |||
m_list.Hide();
| |||
//--- call of the method of the parent class
| |||
return(CWnd::Show());
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::Save(const int file_handle)
| |||
{
| |||
//--- check
| |||
if(file_handle==INVALID_HANDLE)
| |||
return(false);
| |||
//---
| |||
FileWriteLong(file_handle,Value());
| |||
//--- succeed
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::Load(const int file_handle)
| |||
{
| |||
//--- check
| |||
if(file_handle==INVALID_HANDLE)
| |||
return(false);
| |||
//---
| |||
if(!FileIsEnding(file_handle))
| |||
SelectByValue(FileReadLong(file_handle));
| |||
//--- succeed
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Handler of click on main entry field |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::OnClickEdit(void)
| |||
{
| |||
//--- change button state
| |||
if(!m_drop.Pressed(!m_drop.Pressed()))
| |||
return(false);
| |||
//--- call the click on button handler
| |||
return(OnClickButton());
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Handler of click on button |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::OnClickButton(void)
| |||
{
| |||
//--- show or hide the drop-down list depending on the button state
| |||
return((m_drop.Pressed()) ? ListShow() : ListHide());
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Handler of click on drop-down list |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::OnChangeList(void)
| |||
{
| |||
string text=m_list.Select();
| |||
//--- hide the list, depress the button
| |||
ListHide();
| |||
m_drop.Pressed(false);
| |||
//--- set text in the main entry field
| |||
m_edit.Text(text);
| |||
//--- send notification
| |||
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
| |||
//--- handled
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Show the drop-down list |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::ListShow(void)
| |||
{
| |||
BringToTop();
| |||
//--- show the list
| |||
return(m_list.Show());
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Hide drop-down list |
| |||
//+------------------------------------------------------------------+
| |||
bool CComboBox::ListHide(void)
| |||
{
| |||
//--- hide the list
| |||
return(m_list.Hide());
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Hide the drop-down element if necessary |
| |||
//+------------------------------------------------------------------+
| |||
void CComboBox::CheckListHide(const int id,int x,int y)
| |||
{
| |||
//--- check event ID
| |||
if(id!=CHARTEVENT_CLICK)
| |||
return;
| |||
//--- check visibility of the drop-down element
| |||
if(!m_list.IsVisible())
| |||
return;
| |||
//--- check mouse cursor's position
| |||
y-=(int)ChartGetInteger(m_chart_id,CHART_WINDOW_YDISTANCE,m_subwin);
| |||
if(!m_edit.Contains(x,y) && !m_list.Contains(x,y))
| |||
{
| |||
m_drop.Pressed(false);
| |||
m_list.Hide();
| |||
}
| |||
}
| |||
//+------------------------------------------------------------------+
|