MobinMQL/Include/Controls/WndContainer.mqh
2025-07-22 14:47:41 +03:00

473 lines
16 KiB
MQL5

//+------------------------------------------------------------------+
//| WndContainer.mqh |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#include "Wnd.mqh"
#include <Arrays\ArrayObj.mqh>
//+------------------------------------------------------------------+
//| Class CWndContainer |
//| Usage: base class of the combined control |
//+------------------------------------------------------------------+
class CWndContainer : public CWnd
{
private:
CArrayObj m_controls; // container of the control
public:
CWndContainer(void);
~CWndContainer(void);
//--- release memory
virtual void Destroy(const int reason=0);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
virtual bool OnMouseEvent(const int x,const int y,const int flags);
//--- access the contents of container
int ControlsTotal(void) const { return(m_controls.Total()); }
CWnd* Control(const int ind) const { return(dynamic_cast<CWnd *>(m_controls.At(ind))); }
virtual CWnd* ControlFind(const long id);
//--- for mouse cursor focus
virtual bool MouseFocusKill(const long id=-1);
//--- fill
bool Add(CWnd *control);
bool Add(CWnd &control);
//--- underflowing
bool Delete(CWnd *control);
bool Delete(CWnd &control);
//--- geometry
virtual bool Move(const int x,const int y);
virtual bool Move(const CPoint &point);
virtual bool Shift(const int dx,const int dy);
//--- ID
virtual long Id(const long id);
long Id(void) const { return(CWnd::Id()); }
//--- state
virtual bool Enable(void);
virtual bool Disable(void);
virtual bool Show(void);
virtual bool Hide(void);
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
protected:
//--- internal event handlers
virtual bool OnResize(void);
virtual bool OnActivate(void);
virtual bool OnDeactivate(void);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
bool CWndContainer::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
//--- if an object is being dragged, pass control to the special drag object
if(m_drag_object!=NULL && m_drag_object.OnEvent(id,lparam,dparam,sparam))
return(true);
//--- loop by elements of group
int total=m_controls.Total();
for(int i=total-1;i>=0;i--)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
if(control.OnEvent(id,lparam,dparam,sparam))
return(true);
}
//--- not handled
return(false);
}
//+------------------------------------------------------------------+
//| Common handler of mouse events |
//+------------------------------------------------------------------+
bool CWndContainer::OnMouseEvent(const int x,const int y,const int flags)
{
if(!IS_VISIBLE)
return(false);
//--- if an object is being dragged, pass control to the special drag object
if(m_drag_object!=NULL && m_drag_object.OnMouseEvent(x,y,flags))
return(true);
//--- loop by elements of group
int total=m_controls.Total();
for(int i=total-1;i>=0;i--)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
if(control.OnMouseEvent(x,y,flags))
return(true);
}
//--- call of the method of the parent class
return(CWnd::OnMouseEvent(x,y,flags));
}
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CWndContainer::CWndContainer(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CWndContainer::~CWndContainer(void)
{
}
//+------------------------------------------------------------------+
//| Delete group of controls |
//+------------------------------------------------------------------+
void CWndContainer::Destroy(const int reason)
{
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(0);
//--- check of pointer
if(control==NULL)
continue;
control.Destroy();
m_controls.Delete(0);
}
}
//+------------------------------------------------------------------+
//| Find control by specified ID |
//+------------------------------------------------------------------+
CWnd* CWndContainer::ControlFind(const long id)
{
CWnd *result=CWnd::ControlFind(id);
//---
if(result!=NULL)
return(result);
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
result=control.ControlFind(id);
if(result!=NULL)
break;
}
//--- return the result
return(result);
}
//+------------------------------------------------------------------+
//| Remove the mouse focus from control |
//+------------------------------------------------------------------+
bool CWndContainer::MouseFocusKill(const long id=-1)
{
if(!IS_ACTIVE)
return(false);
Deactivate();
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.MouseFocusKill();
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Add control to the group (by pointer) |
//+------------------------------------------------------------------+
bool CWndContainer::Add(CWnd *control)
{
//--- check of pointer
if(control==NULL)
return(false);
//--- correct the coordinates of added control
control.Shift(Left(),Top());
//--- "projecting" the group flag "visibility" to the added element
if(IS_VISIBLE && control.IsVisible())
{
//--- element will be "visible" only if the group is "visible" and the element is completely "within" this group
control.Visible(Contains(control));
}
else
control.Hide();
//--- "projecting" the group flag "enabled" to the added element
if(IS_ENABLED)
control.Enable();
else
control.Disable();
//--- adding
return(m_controls.Add(control));
}
//+------------------------------------------------------------------+
//| Add control to the group (by reference) |
//+------------------------------------------------------------------+
bool CWndContainer::Add(CWnd &control)
{
//--- add by pointer
return(Add((CWnd*)GetPointer(control)));
}
//+------------------------------------------------------------------+
//| Delete control from the group (by pointer) |
//+------------------------------------------------------------------+
bool CWndContainer::Delete(CWnd *control)
{
//--- check of pointer
if(control==NULL)
return(false);
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *pointer=Control(i);
//--- check of pointer
if(pointer==NULL)
continue;
//--- delete item from group
if(pointer==control)
return(m_controls.Delete(i));
}
//--- failure
return(false);
}
//+------------------------------------------------------------------+
//| Delete control from the group (by reference) |
//+------------------------------------------------------------------+
bool CWndContainer::Delete(CWnd &control)
{
//--- delete by pointer
return(Delete((CWnd*)GetPointer(control)));
}
//+------------------------------------------------------------------+
//| Absolute movement of the controls group |
//+------------------------------------------------------------------+
bool CWndContainer::Move(const int x,const int y)
{
//--- relative movement
return(Shift(x-Left(),y-Top()));
}
//+------------------------------------------------------------------+
//| Absolute movement of the controls group |
//+------------------------------------------------------------------+
bool CWndContainer::Move(const CPoint &point)
{
//--- relative movement
return(Shift(point.x-Left(),point.y-Top()));
}
//+------------------------------------------------------------------+
//| Relative movement of the controls group |
//+------------------------------------------------------------------+
bool CWndContainer::Shift(const int dx,const int dy)
{
//--- call of the method of the parent class
if(!CWnd::Shift(dx,dy)) return(false);
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
//--- move the group item
control.Shift(dx,dy);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set ID of control |
//+------------------------------------------------------------------+
long CWndContainer::Id(const long id)
{
//--- reserve ID for container
long id_used=1;
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
id_used+=control.Id(id+id_used);
}
m_id=id;
//--- return number of used IDs
return(id_used);
}
//+------------------------------------------------------------------+
//| Enables event handling by the group of controls |
//+------------------------------------------------------------------+
bool CWndContainer::Enable(void)
{
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.Enable();
}
//--- call of the method of the parent class
return(CWnd::Enable());
}
//+------------------------------------------------------------------+
//| Disables event handling by the group of controls |
//+------------------------------------------------------------------+
bool CWndContainer::Disable(void)
{
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.Disable();
}
//--- call of the method of the parent class
return(CWnd::Disable());
}
//+------------------------------------------------------------------+
//| Makes the group of controls visible |
//+------------------------------------------------------------------+
bool CWndContainer::Show(void)
{
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.Show();
}
//--- call of the method of the parent class
return(CWnd::Show());
}
//+------------------------------------------------------------------+
//| Makes the group of controls hidden |
//+------------------------------------------------------------------+
bool CWndContainer::Hide(void)
{
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.Hide();
}
//--- call of the method of the parent class
return(CWnd::Hide());
}
//+------------------------------------------------------------------+
//| Handler of resizing |
//+------------------------------------------------------------------+
bool CWndContainer::OnResize()
{
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
if(!control.Align(Rect()))
return(false);
}
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of activating the group of controls |
//+------------------------------------------------------------------+
bool CWndContainer::OnActivate(void)
{
if(IS_ACTIVE)
return(false);
Activate();
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.Activate();
}
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of deactivating the group of controls |
//+------------------------------------------------------------------+
bool CWndContainer::OnDeactivate(void)
{
if(!IS_ACTIVE)
return(false);
Deactivate();
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.Deactivate();
}
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Save |
//+------------------------------------------------------------------+
bool CWndContainer::Save(const int file_handle)
{
bool result=true;
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
result&=control.Save(file_handle);
}
//--- result
return(result);
}
//+------------------------------------------------------------------+
//| Load |
//+------------------------------------------------------------------+
bool CWndContainer::Load(const int file_handle)
{
bool result=true;
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
result&=control.Load(file_handle);
}
//--- result
return(result);
}
//+------------------------------------------------------------------+