//+------------------------------------------------------------------+
//|                                                ButtonListBox.mqh |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
#property strict    // Necessary for mql4
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "ElementsListBox.mqh"
//+------------------------------------------------------------------+
//| ButtonListBox object class of WForms controls                    |
//+------------------------------------------------------------------+
class CButtonListBox : public CElementsListBox
  {
private:
//--- Create a new graphical object
   virtual CGCnvElement *CreateNewGObject(const ENUM_GRAPH_ELEMENT_TYPE type,
                                          const int element_num,
                                          const string descript,
                                          const int x,
                                          const int y,
                                          const int w,
                                          const int h,
                                          const color colour,
                                          const uchar opacity,
                                          const bool movable,
                                          const bool activity);
public:
//--- Create the specified number of Button objects
   void              CreateButton(const int count,const int width,const int height,const int new_column_width=0,const bool autosize=true);

protected:
//--- Protected constructor with object type, chart ID and subwindow
                     CButtonListBox(const ENUM_GRAPH_ELEMENT_TYPE type,
                                    CGCnvElement *main_obj,CGCnvElement *base_obj,
                                    const long chart_id,
                                    const int subwindow,
                                    const string descript,
                                    const int x,
                                    const int y,
                                    const int w,
                                    const int h);
public:
//--- Constructor
                     CButtonListBox(CGCnvElement *main_obj,CGCnvElement *base_obj,
                                    const long chart_id,
                                    const int subwindow,
                                    const string descript,
                                    const int x,
                                    const int y,
                                    const int w,
                                    const int h);

//--- (1) Set and (2) return the group of the button specified by index
   void              SetButtonGroup(const int index,const int group);
   int               ButtonGroup(const int index);
//--- (1) Set and (2) return the flag of the group button specified by the button index
   void              SetButtonGroupFlag(const int index,const bool flag);
   bool              ButtonGroupFlag(const int index);
//--- Sets the specified button "multiselect" mode
   void              SetMultiSelect(const bool flag);
//--- (1) Set and (2) return the "Toggle button" flag of the button specified by index
   void              SetButtonToggle(const int index,const bool flag);
   bool              ButtonToggle(const int index);
//--- Set the "Toggle button" flag for all buttons of the object
   void              SetToggle(const bool flag);
   
  };
//+------------------------------------------------------------------+
//| Protected constructor with an object type,                       |
//| chart ID and subwindow                                           |
//+------------------------------------------------------------------+
CButtonListBox::CButtonListBox(const ENUM_GRAPH_ELEMENT_TYPE type,
                               CGCnvElement *main_obj,CGCnvElement *base_obj,
                               const long chart_id,
                               const int subwindow,
                               const string descript,
                               const int x,
                               const int y,
                               const int w,
                               const int h) : CElementsListBox(type,main_obj,base_obj,chart_id,subwindow,descript,x,y,w,h)
  {
//--- Set the specified graphical element type for the object and assign the library object type to the current object
   this.SetTypeElement(type);
   this.m_type=OBJECT_DE_TYPE_GWF_COMMON;
   this.SetBorderSizeAll(1);
   this.SetBorderStyle(FRAME_STYLE_SIMPLE);
   this.SetBorderColor(CLR_DEF_BORDER_COLOR,true);
   this.SetForeColor(CLR_DEF_FORE_COLOR,true);
  }
//+------------------------------------------------------------------+
//| Constructor indicating the main and base objects,                |
//| chart ID and subwindow                                           |
//+------------------------------------------------------------------+
CButtonListBox::CButtonListBox(CGCnvElement *main_obj,CGCnvElement *base_obj,
                               const long chart_id,
                               const int subwindow,
                               const string descript,
                               const int x,
                               const int y,
                               const int w,
                               const int h) : CElementsListBox(GRAPH_ELEMENT_TYPE_WF_BUTTON_LIST_BOX,main_obj,base_obj,chart_id,subwindow,descript,x,y,w,h)
  {
   this.SetTypeElement(GRAPH_ELEMENT_TYPE_WF_BUTTON_LIST_BOX);
   this.m_type=OBJECT_DE_TYPE_GWF_COMMON;
   this.SetBorderSizeAll(1);
   this.SetBorderStyle(FRAME_STYLE_SIMPLE);
   this.SetBorderColor(CLR_DEF_BORDER_COLOR,true);
   this.SetForeColor(CLR_DEF_FORE_COLOR,true);
  }
//+------------------------------------------------------------------+
//| Create the specified number of Button objects                    |
//+------------------------------------------------------------------+
void CButtonListBox::CreateButton(const int count,const int width,const int height,const int new_column_width=0,const bool autosize=true)
  {
//--- Create the pointer to the Button object
   CButton *obj=NULL;
//--- Create the specified number of Button objects
   CElementsListBox::CreateElements(GRAPH_ELEMENT_TYPE_WF_BUTTON,count,2,2,width,height,new_column_width,autosize);
//--- In the loop by the created number of objects
   for(int i=0;i<this.ElementsTotal();i++)
     {
      //--- Get the created object from the list by the loop index
      obj=this.GetElement(i);
      //--- If the object could not be obtained, send the appropriate message to the log and move on to the next one
      if(obj==NULL)
        {
         ::Print(DFUN,MSG_ELM_LIST_ERR_FAILED_GET_GRAPH_ELEMENT_OBJ,this.TypeElementDescription(GRAPH_ELEMENT_TYPE_WF_BUTTON));
         continue;
        }
      //--- Set left center text alignment
      obj.SetTextAlign(ANCHOR_CENTER);
      //--- Set the object text
      obj.SetText(TypeGraphElementAsString(obj.TypeGraphElement())+string(i+1));
     }
//--- If the flag of auto resizing the base object is passed to the method,
//--- set the auto resize mode to "increase and decrease"
   if(autosize)
      this.SetAutoSizeMode(CANV_ELEMENT_AUTO_SIZE_MODE_GROW_SHRINK,false);
  }
//+------------------------------------------------------------------+
//| Create a new graphical object                                    |
//+------------------------------------------------------------------+
CGCnvElement *CButtonListBox::CreateNewGObject(const ENUM_GRAPH_ELEMENT_TYPE type,
                                               const int obj_num,
                                               const string descript,
                                               const int x,
                                               const int y,
                                               const int w,
                                               const int h,
                                               const color colour,
                                               const uchar opacity,
                                               const bool movable,
                                               const bool activity)
  {
//--- create the CButton object
   CGCnvElement *element=new CButton(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h);
   if(element==NULL)
      ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),this.TypeElementDescription(type));
//--- set the object relocation flag and relative coordinates
   element.SetMovable(movable);
   element.SetCoordXRelative(element.CoordX()-this.CoordX());
   element.SetCoordYRelative(element.CoordY()-this.CoordY());
   return element;
  }
//+------------------------------------------------------------------+
//| Set the group of the button specified by index                   |
//+------------------------------------------------------------------+
void CButtonListBox::SetButtonGroup(const int index,const int group)
  {
   CButton *butt=this.GetElement(index);
   if(butt==NULL)
     {
      ::Print(DFUN,CMessage::Text(MSG_BUTT_LIST_ERR_FAILED_SET_GROUP_BUTTON),(string)index);
      return;
     }
   butt.SetGroup(group);
  }
//+------------------------------------------------------------------+
//| Return the group of the button specified by index                |
//+------------------------------------------------------------------+
int CButtonListBox::ButtonGroup(const int index)
  {
   CButton *butt=this.GetElement(index);
   return(butt!=NULL ? butt.Group() : WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//| Set the flag of the group button specified by the button index   |
//+------------------------------------------------------------------+
void CButtonListBox::SetButtonGroupFlag(const int index,const bool flag)
  {
   CButton *butt=this.GetElement(index);
   if(butt==NULL)
     {
      ::Print(DFUN,CMessage::Text(MSG_BUTT_LIST_ERR_FAILED_SET_GROUP_BUTTON),(string)index);
      return;
     }
   butt.SetGroupButtonFlag(flag);
  }
//+------------------------------------------------------------------+
//| Return the flag of the group button specified by the button index|
//+------------------------------------------------------------------+
bool CButtonListBox::ButtonGroupFlag(const int index)
  {
   CButton *butt=this.GetElement(index);
   return(butt!=NULL ? butt.GroupButtonFlag() : false);
  }
//+------------------------------------------------------------------+
//| Set the "multiselect" mode of the buttons                        |
//+------------------------------------------------------------------+
void CButtonListBox::SetMultiSelect(const bool flag)
  {
   int group=this.Group()+(flag ? 1 : 0);
   for(int i=0;i<this.ElementsTotal();i++)
      this.SetButtonGroup(i,group+(flag ? i : 0));
  }
//+------------------------------------------------------------------+
//| Set the "Toggle button" flag                                     |
//| button specified by index                                        |
//+------------------------------------------------------------------+
void CButtonListBox::SetButtonToggle(const int index,const bool flag)
  {
   CButton *butt=this.GetElement(index);
   if(butt==NULL)
     {
      ::Print(DFUN,CMessage::Text(MSG_BUTT_LIST_ERR_FAILED_SET_TOGGLE_BUTTON),(string)index);
      return;
     }
   butt.SetToggleFlag(flag);
  }
//+------------------------------------------------------------------+
//| Return the "Toggle button" flag                                  |
//| button specified by index                                        |
//+------------------------------------------------------------------+
bool CButtonListBox::ButtonToggle(const int index)
  {
   CButton *butt=this.GetElement(index);
   return(butt!=NULL ? butt.Toggle() : false);
  }
//+------------------------------------------------------------------+
//| Set the "Toggle button" flag to all buttons of the object        |
//+------------------------------------------------------------------+
void CButtonListBox::SetToggle(const bool flag)
  {
   for(int i=0;i<this.ElementsTotal();i++)
      this.SetButtonToggle(i,flag);
  }
//+------------------------------------------------------------------+
