Files
include/Controls/ComboBox_New.mqh
T
2025-02-07 19:06:08 +03:30

355 lines
14 KiB
Plaintext

//+------------------------------------------------------------------+
//| ComboBox_New.mqh |
//| Copyright 2000-2024, 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
bool flage; // hidhe or show combobox
static bool s_list_shown; // Static flag to track if any list is shown
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; }
bool CheckShowHide(void) {return flage;}
//--- 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()); }
// virtual void SetBacgroundItem(color BcGI, color BcGITS) {m_list.SetBackGroundItem(BcGI,BcGITS);}
static bool IsAnyListShown(void) { return(s_list_shown); }
//--- data
string Select(void) { return(m_edit.Text()); }
bool Select(const int index);
bool SelectByText(const string text);
bool SelectByValue(const long value);
void ChangeComboBoxListState(void);
//--- 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);
};
bool CComboBox::s_list_shown = false; // Initialize static member
//+------------------------------------------------------------------+
//| 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)
{
Print("flag 1 ",flage);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CComboBox::~CComboBox(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CComboBox::Create(const long chart,const string name,const int subwin, 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);
Print("flag 2 ",flage);
//--- 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)
{
Print("flag 3 ",flage);
//--- 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);
Print("flag 4 ",flage);
//--- 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();
Print("flag 5 ",flage);
//--- 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);
Print("flag 6 ",flage);
//--- call the click on button handler
return(OnClickButton());
}
//+------------------------------------------------------------------+
//| Handler of click on button |
//+------------------------------------------------------------------+
bool CComboBox::OnClickButton(void)
{
Print("flag 7 ",flage);
//--- 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);
Print("flag 8 ",flage);
//--- 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)
{
if(CComboBox::IsAnyListShown())
ListHide();
BringToTop();
CComboBox::s_list_shown = true;
//--- show the list
flage = true;
return(m_list.Show());
}
//+------------------------------------------------------------------+
//| Hide drop-down list |
//+------------------------------------------------------------------+
bool CComboBox::ListHide(void)
{
CComboBox::s_list_shown = false;
//--- hide the list
flage = false;
return(m_list.Hide());
}
//+------------------------------------------------------------------+
//| Hide the drop-down element if necessary |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Hide the drop-down element if necessary |
//+------------------------------------------------------------------+
void CComboBox::CheckListHide(const int id,int x,int y)
{
// If the event is not a mouse click or mouse move, return
if (id != CHARTEVENT_CLICK && id != CHARTEVENT_MOUSE_MOVE)
return;
// If the list is not visible, return
if (!m_list.IsVisible())
return;
// Adjust the coordinates based on the chart window
y -= (int)ChartGetInteger(m_chart_id, CHART_WINDOW_YDISTANCE, m_subwin);
// Check if the mouse click is inside the combo box or the list
if (!m_edit.Contains(x, y) && !m_list.Contains(x, y))
{
// If the click is outside, hide the list
ListHide(); // Use ListHide() to clear the static flag
m_drop.Pressed(false);
}
}