//+------------------------------------------------------------------+
//|                                                  ProgressBar.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 "..\Containers\Container.mqh"
#include "..\Helpers\BarProgressBar.mqh"
//+------------------------------------------------------------------+
//| CProgressBar object class of the WForms controls                 |
//+------------------------------------------------------------------+
class CProgressBar : public CContainer
  {
private:
   int               m_progress_bar_max;           // Maximum progress bar width
   int               m_value_by_max;               // Value relative to Maximum
   int               m_progress_bar_text_x;        // X coordinate of the text label with the description of the progress bar
   int               m_progress_bar_text_y;        // Y coordinate of the text label with the description of the progress bar
   color             m_progress_bar_text_color;    // Color of the text describing the progress bar
   uchar             m_progress_bar_text_opacity;  // Opacity of the text describing the progress bar
   string            m_progress_bar_text;          // Text describing the progress bar
   ENUM_FRAME_ANCHOR m_progress_bar_text_anchor;   // Method for binding the text with a progress bar description
//--- 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);
//--- Create the progress bar object
   void              CreateProgressBar(void);
//--- Calculate the progress bar width
   int               CalculateProgressBarWidth(void);
//--- Initialize the element properties
   void              Initialize(void);

protected:
//--- Protected constructor with object type, chart ID and subwindow
                     CProgressBar(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:
//--- (1) Set and (2) return the animation speed of the progress bar in case of the Marquee style
   void              SetMarqueeAnimationSpeed(const int value)
                       {
                        this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MARQUEE_ANIM_SPEED,value);
                        CBarProgressBar *bar=this.GetProgressBar();
                        if(bar!=NULL)
                           bar.SetMarqueeAnimationSpeed(value);
                       }
   int               MarqueeAnimationSpeed(void)   const { return (int)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MARQUEE_ANIM_SPEED);  }

//--- (1) Set and (2) return the progress bar style
   void              SetStyle(const ENUM_CANV_ELEMENT_PROGRESS_BAR_STYLE style)
                       {
                        this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_STYLE,style);
                        CBarProgressBar *bar=this.GetProgressBar();
                        if(bar!=NULL)
                           bar.SetStyle(style);
                       }
   ENUM_CANV_ELEMENT_PROGRESS_BAR_STYLE Style(void) const
                       { return (ENUM_CANV_ELEMENT_PROGRESS_BAR_STYLE)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_STYLE);          }

//--- (1) Set and (2) return the progress bar increment to redraw it
   void              SetStep(const int value)
                       {
                        this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_STEP,value);
                        CBarProgressBar *bar=this.GetProgressBar();
                        if(bar!=NULL)
                           bar.SetStep(value);
                       }
   int               Step(void)                          const { return (int)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_STEP);    }
   
//--- (1) Set and (2) return the current value of the progress bar in the range from Min to Max as a number and (3) as a text
   void              SetValue(const int value);
   int               Value(void)                         const { return (int)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_VALUE);   }
   string            ValueDescription(void)              const { return (string)this.Value();                                          }
//--- Return the current progress bar value in the range from Min to Max as a percentage in the form of (1) a number and (2) a text
   double            ValuePercent(void) const;
   string            ValuePercentDescription(void)       const { return ::DoubleToString(this.ValuePercent(),2)+"%";                   }
   
//--- (1) Set and (2) return the upper bound of the ProgressBar operating range
   void              SetMaximum(const int value)               { this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MAXIMUM,value);       }
   int               Maximum(void)                       const { return (int)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MAXIMUM); }
   
//--- (1) Set and (2) return the lower bound of the ProgressBar operating range
   void              SetMinimum(const int value)               { this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MINIMUM,value);       }
   int               Minimum(void)                       const { return (int)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MINIMUM); }
   
//--- Set (1) style, (2) opacity and (3) color for the glare object
   void              SetGlareStyle(const ENUM_CANV_ELEMENT_VISUAL_EFF_STYLE style);
   void              SetGlareOpacity(const uchar opacity);
   void              SetGlareColor(const color clr);

//--- Return the pointer to the (1) progress bar object, (2) glare object and (3) the text label object with the progress bar description
   CBarProgressBar  *GetProgressBar(void)                { return this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_BAR_PROGRESS_BAR,0);     }
   CGlareObj        *GetGlareObj(void)                   { return this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_GLARE_OBJ,0);            }
   CLabel           *GetProgressDescriptionObj(void)     { return this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_LABEL,0);                }

//--- Set the (1) text, (2) color
//--- (3) opacity, (4) X, (5) Y coordinates, (6) font, (7) size and (8) font flags to the progress bar text label
   void              SetBarDescriptionText(const string text,const bool redraw=false);
   void              SetBarDescriptionColor(const color clr,const bool redraw=false,const bool set_init_color=false);
   void              SetBarDescriptionOpacity(const uchar opacity,const bool redraw=false);
   void              SetBarDescriptionX(const int x,const bool redraw=false);
   void              SetBarDescriptionY(const int y,const bool redraw=false);
   void              SetBarDescriptionFontName(const string font,const bool redraw=false);
   void              SetBarDescriptionFontSize(const int size,const bool relative=false,const bool redraw=false);
   void              SetBarDescriptionFontFlags(const uint flags,const bool redraw=false);
   
//--- (1) hide and (2) display the progress bar text label
   void              HideBarDescription(void);
   void              ShowBarDescription(void);
     
//--- Resets the progress bar values to the set minimum
   void              ResetProgressBar(void)              { this.SetValue(this.Minimum());    }
//--- Set the element width
   virtual bool      SetWidth(const int width);
//--- Initialize values for handling in PerformStep
   void              SetValuesForProcessing(const int minimum,const int maximum,const int step,const int steps_skipped);
//--- Increase the current position of the progress bar by the step value
   void              PerformStep();

//--- Supported object properties (1) integer, (2) real and (3) string ones
   virtual bool      SupportProperty(ENUM_CANV_ELEMENT_PROP_INTEGER property) { return true; }
   virtual bool      SupportProperty(ENUM_CANV_ELEMENT_PROP_DOUBLE property)  { return true; }
   virtual bool      SupportProperty(ENUM_CANV_ELEMENT_PROP_STRING property)  { return true; }
   
//--- Constructor
                     CProgressBar(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);
//--- Timer
   virtual void      OnTimer(void);
  };
//+------------------------------------------------------------------+
//| Protected constructor with an object type,                       |
//| chart ID and subwindow                                           |
//+------------------------------------------------------------------+
CProgressBar::CProgressBar(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) : CContainer(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.Initialize();
   this.CreateProgressBar();
  }
//+------------------------------------------------------------------+
//| Constructor indicating the main and base objects,                |
//| chart ID and subwindow                                           |
//+------------------------------------------------------------------+
CProgressBar::CProgressBar(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) : CContainer(GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR,main_obj,base_obj,chart_id,subwindow,descript,x,y,w,h)
  {
   this.SetTypeElement(GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR);
   this.m_type=OBJECT_DE_TYPE_GWF_COMMON;
   this.Initialize();
   this.CreateProgressBar();
  }
//+------------------------------------------------------------------+
//| Initialize the element properties                                |
//+------------------------------------------------------------------+
void CProgressBar::Initialize(void)
  {
   this.SetBorderSizeAll(1);
   this.SetBorderStyle(FRAME_STYLE_SIMPLE);
   this.SetBackgroundColor(CLR_DEF_CONTROL_PROGRESS_BAR_BACK_COLOR,true);
   this.SetBorderColor(CLR_DEF_CONTROL_PROGRESS_BAR_BORDER_COLOR,true);
   this.SetForeColor(CLR_DEF_CONTROL_PROGRESS_BAR_FORE_COLOR,true);
   this.SetMarqueeAnimationSpeed(10);
   this.SetMaximum(100);
   this.SetMinimum(0);
   this.SetValue(50);
   this.SetStep(10);
   this.SetStyle(CANV_ELEMENT_PROGRESS_BAR_STYLE_CONTINUOUS);
   this.m_progress_bar_max=this.Width()-this.BorderSizeLeft()-this.BorderSizeRight();
   this.m_value_by_max=this.Value()*100/this.Maximum();
   this.m_progress_bar_text="";
   this.m_progress_bar_text_x=1;
   this.m_progress_bar_text_y=0;
   this.m_progress_bar_text_color=CLR_DEF_CONTROL_PROGRESS_BAR_FORE_COLOR;
   this.m_progress_bar_text_opacity=255;
   this.m_progress_bar_text_anchor=FRAME_ANCHOR_LEFT_TOP;
  }
//+------------------------------------------------------------------+
//| Create the progress bar object                                   |
//+------------------------------------------------------------------+
void CProgressBar::CreateProgressBar(void)
  {
//--- Set the length of the progress bar equal to the object Value()
//--- The height of the progress bar is set equal to the height of the object minus the top and bottom border sizes
   int w=this.CalculateProgressBarWidth();
   int h=this.Height()-this.BorderSizeTop()-this.BorderSizeBottom();
   if(h<1)
      h=1;
//--- Create the progress bar object
   this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_BAR_PROGRESS_BAR,0,0,w,h,clrNONE,255,false,false);
//--- Create a description of the progress bar, get the text label object and set the default parameters
   this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_LABEL,1,0,this.Width()-2,this.Height()-2,clrNONE,0,false,false);
   CLabel *obj=this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_LABEL,0);
   if(obj!=NULL)
     {
      obj.SetText(this.m_progress_bar_text);
      obj.SetFontName(DEF_FONT);
      obj.SetFontSize(DEF_FONT_SIZE);
      obj.SetTextAnchor(FRAME_ANCHOR_LEFT_TOP);
      obj.SetTextAlign(ANCHOR_LEFT_UPPER);
      this.HideBarDescription();
     }
//--- Create the glare object
   this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_GLARE_OBJ,0,0,w,h,CLR_CANV_NULL,0,true,false);
//--- Add the current CProgressBar object to the list of active elements of the collection
   this.AddObjToListActiveElements();
  }
//+------------------------------------------------------------------+
//| Create a new graphical object                                    |
//+------------------------------------------------------------------+
CGCnvElement *CProgressBar::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)
  {
   CGCnvElement *element=NULL;
   switch(type)
     {
      case GRAPH_ELEMENT_TYPE_WF_BAR_PROGRESS_BAR  :
         element=new CBarProgressBar(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h);
        break;
      case GRAPH_ELEMENT_TYPE_WF_GLARE_OBJ         :
         element=new CGlareObj(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h);
        break;
      case GRAPH_ELEMENT_TYPE_WF_LABEL             :
         element=new CLabel(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h);
        break;
      default:
        break;
     }
   if(element==NULL)
      ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),this.TypeElementDescription(type));
   return element;
  }
//+------------------------------------------------------------------+
//| Timer                                                            |
//+------------------------------------------------------------------+
void CProgressBar::OnTimer(void)
  {
   CBarProgressBar *bar=this.GetProgressBar();
   if(bar!=NULL)
     {
      if(bar.Style()==CANV_ELEMENT_PROGRESS_BAR_STYLE_MARQUEE)
        {
         int x=bar.CoordX()+8;
         if(x>this.RightEdge())
            x=this.CoordX()-bar.Width();
         bar.Move(x,bar.CoordY());
         bar.Redraw(true);
        }
      else
         bar.OnTimer();
     }
  }
//+------------------------------------------------------------------+
//| Initialize values for handling in PerformStep                    |
//+------------------------------------------------------------------+
void CProgressBar::SetValuesForProcessing(const int minimum,const int maximum,const int step,const int steps_skipped)
  {
   this.SetMinimum(minimum<0 ? 0 : minimum);
   this.SetMaximum(maximum<this.Minimum() ? this.Minimum() : maximum);
   this.SetStep(step<0 ? 0 : step);
  }
//+------------------------------------------------------------------+
//| Set the current value of the progress bar                        |
//+------------------------------------------------------------------+
void CProgressBar::SetValue(const int value)
  {
//--- Correct the value passed to the method and set it to the object property
   int v=(value<this.Minimum() ? this.Minimum() : value>this.Maximum() ? this.Maximum() : value);
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_VALUE,v);
//--- Get the progress bar object
   CBarProgressBar *bar=this.GetProgressBar();
   if(bar!=NULL)
     {
      //--- Set 'value' for the progress bar
      bar.SetValue(v);
      //--- Calculate the width of the progress bar object
      int w=this.CalculateProgressBarWidth();
      //--- If the calculated width is greater than the maximum possible value, set the maximum width
      if(w>this.m_progress_bar_max)
         w=this.m_progress_bar_max;
      //--- If the width is less than 1, then
      if(w<1)
        {
         //--- hide the progress bar and redraw the chart to display changes immediately
         bar.Hide();
         ::ChartRedraw(bar.ChartID());
        }
      //--- If the width value is not less than 1
      else
        {
         //--- If the progress bar is hidden, display it and
         if(!bar.IsVisible())
            bar.Show();
         //--- If the style of the progress bar is "Continuous line", change the width of the object to the calculated value
         if(this.Style()==CANV_ELEMENT_PROGRESS_BAR_STYLE_CONTINUOUS)
            bar.Resize(w,bar.Height(),true);
         //--- Otherwise, if the progress bar style is "Segmented blocks"
         else if(this.Style()==CANV_ELEMENT_PROGRESS_BAR_STYLE_BLOCKS)
           {
            //--- Segment width including indent
            int wd=bar.SegmentWidth()+bar.SegmentDistance();
            //--- The number of segments that fit the width of the progress bar
            int num=w/(wd>0 ? wd : 1);
            //--- The X coordinate of the last segment calculated from the beginning of the segment count
            int wx=bar.SegmentStart()+num*wd;
            //--- If the calculated width of the progress bar is less than the coordinate of the last segment, and this is not the last segment,
            //--- set the width of the progress bar equal to the penultimate segment coordinate
            if(w<wx-bar.SegmentDistance() && w<this.m_progress_bar_max)
               w=wx-wd+bar.SegmentDistance();
            //--- If the calculated width of the progress bar is less than the coordinate of the last segment, or it is not the last segment,
            if(w<wx-bar.SegmentDistance() || w==this.m_progress_bar_max)
               //--- change the size of the progress bar in accordance with the received and adjusted width
               bar.Resize(w,bar.Height(),true);
           }
        }
      //--- If the progress bar description text is set,
      if(this.m_progress_bar_text!="")
        {
         //--- get the object description of the progress bar and bring it to the foreground
         CLabel *obj=this.GetProgressDescriptionObj();
         if(obj!=NULL)
            obj.BringToTop();
        }
     }
  }
//+---------------------------------------------------------------------+
//| Increase the current position of the progress bar by the step value |
//+---------------------------------------------------------------------+
void CProgressBar::PerformStep(void)
  {
   this.SetValue(this.Value()+this.Step());
  }
//+------------------------------------------------------------------+
//| Calculate the width of the progress bar                          |
//+------------------------------------------------------------------+
int CProgressBar::CalculateProgressBarWidth(void)   

  {
   this.m_value_by_max=this.Value()*100/this.Maximum();
   return(this.Style()==CANV_ELEMENT_PROGRESS_BAR_STYLE_MARQUEE ? this.m_progress_bar_max/2 : this.m_progress_bar_max*this.m_value_by_max/100);
  }
//+------------------------------------------------------------------+
//| Set the new width                                                |
//+------------------------------------------------------------------+
bool CProgressBar::SetWidth(const int width)
  {
   if(!CGCnvElement::SetWidth(width))
      return false;
   this.m_progress_bar_max=this.Width()-this.BorderSizeLeft()-this.BorderSizeRight();
   CBarProgressBar *bar=this.GetProgressBar();
   if(bar==NULL)
      return false;
   int w=this.CalculateProgressBarWidth();
   bar.SetWidth(w);
   CLabel *lbl=this.GetProgressDescriptionObj();
   if(lbl!=NULL)
      lbl.SetWidth(w);
   return true;
  }
//+------------------------------------------------------------------+
//| Set the glare object style                                       |
//+------------------------------------------------------------------+
void CProgressBar::SetGlareStyle(const ENUM_CANV_ELEMENT_VISUAL_EFF_STYLE style)
  {
   CGlareObj *obj=this.GetGlareObj();
   if(obj==NULL)
      return;
   obj.SetVisualEffectStyle(style);
  }
//+------------------------------------------------------------------+
//| Set the opacity of the highlight object                          |
//+------------------------------------------------------------------+
void CProgressBar::SetGlareOpacity(const uchar opacity)
  {
   CGlareObj *obj=this.GetGlareObj();
   if(obj==NULL)
      return;
   obj.SetOpacity(opacity);
  }
//+------------------------------------------------------------------+
//| Set the color for the glare object                               |
//+------------------------------------------------------------------+
void CProgressBar::SetGlareColor(const color clr)
  {
   CGlareObj *obj=this.GetGlareObj();
   if(obj==NULL)
      return;
   obj.SetColor(clr);
  }
//+------------------------------------------------------------------+
//| Set a text to the text label of the progress bar                 |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionText(const string text,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   this.m_progress_bar_text=text;
   obj.SetText(text);
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+
//| Set the text color of the progress bar to the text label         |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionColor(const color clr,const bool redraw=false,const bool set_init_color=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   this.m_progress_bar_text_color=clr;
   obj.SetForeColor(clr,false);
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+
//| Set opacity to the progress bar text label                       |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionOpacity(const uchar opacity,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   this.m_progress_bar_text_opacity=opacity;
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+
//| Set the X coordinate to the text label of the progress bar       |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionX(const int x,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   this.m_progress_bar_text_x=x;
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+
//| Set the Y coordinate to the text label of the progress bar       |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionY(const int y,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   this.m_progress_bar_text_y=y;
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+
//| Set the font in the text label of the progress bar               |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionFontName(const string font,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   obj.SetFontName(font);
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+
//| Set the font size to the progress bar text label                 |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionFontSize(const int size,const bool relative=false,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   obj.SetFontSize(size,relative);
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+
//| Set the font flags in the text label of the progress bar         |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionFontFlags(const uint flags,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   obj.SetFontFlags(flags);
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+
//| Hide the progress bar text label                                 |
//+------------------------------------------------------------------+
void CProgressBar::HideBarDescription(void)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   obj.SetDisplayed(false);
   obj.Hide();
  }
//+------------------------------------------------------------------+
//| Display a text label for the progress bar                        |
//+------------------------------------------------------------------+
void CProgressBar::ShowBarDescription(void)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   obj.SetDisplayed(true);
   obj.Show();
  }
//+------------------------------------------------------------------+
//| Return the current value of the progress bar                     |
//| in the range from Min to Max as a percentage                     |
//+------------------------------------------------------------------+
double CProgressBar::ValuePercent(void) const
  {
   double range=this.Maximum()-this.Minimum();
   return(this.Value()*100.0/(range>0 ? range : 1));
  }
//+------------------------------------------------------------------+
