//+------------------------------------------------------------------+
//|                                            ScrollBarVertical.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 "ScrollBarThumb.mqh"
#include "ArrowDownButton.mqh"
#include "ArrowUpButton.mqh"
#include "ScrollBar.mqh"
//+------------------------------------------------------------------+
//| CScrollBarVertical object class of WForms controls               |
//+------------------------------------------------------------------+
class CScrollBarVertical : public CScrollBar
  {
private:
//--- Create the ArrowButton objects
   virtual void      CreateArrowButtons(const int width,const int height);
//--- Calculate the capture area size
   virtual int       CalculateThumbAreaSize(void);

protected:
//--- Protected constructor with object type, chart ID and subwindow
                     CScrollBarVertical(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:
//--- 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; }
   
//--- Return the button with the (1) up, (2) down arrow
   CArrowUpButton   *GetArrowButtonUp(void)     { return this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP,0);      }
   CArrowDownButton *GetArrowButtonDown(void)   { return this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN,0);    }
   
//--- Constructor
                     CScrollBarVertical(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);
//--- Event handler
   virtual void      OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam);
  };
//+------------------------------------------------------------------+
//| Protected constructor with an object type,                       |
//| chart ID and subwindow                                           |
//+------------------------------------------------------------------+
CScrollBarVertical::CScrollBarVertical(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) : CScrollBar(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.CreateThumbArea();
  }
//+------------------------------------------------------------------+
//| Constructor indicating the main and base objects,                |
//| chart ID and subwindow                                           |
//+------------------------------------------------------------------+
CScrollBarVertical::CScrollBarVertical(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) : CScrollBar(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL,main_obj,base_obj,chart_id,subwindow,descript,x,y,w,h)
  {
   this.SetTypeElement(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL);
   this.CreateThumbArea();
  }
//+------------------------------------------------------------------+
//| Create the ArrowButton objects                                   |
//+------------------------------------------------------------------+
void CScrollBarVertical::CreateArrowButtons(const int width,const int height)
  {
//--- Set the size of the buttons equal to the width of the scrollbar without the size of its frame
   int size=this.Thickness()-this.BorderSizeLeft()-this.BorderSizeRight();
//--- Create the buttons with up and down arrows and the area capture object. The arrow size is set to 2
   this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP,  0,0,size,size,this.BackgroundColor(),255,true,false);
   this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN,0,this.BottomEdge()-this.BorderSizeBottom()-2*size,size,size,this.BackgroundColor(),255,true,false);
   this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_THUMB,0,this.Height()/2-height,size,30,CLR_DEF_CONTROL_SCROLL_BAR_THUMB_COLOR,255,true,false);
   this.SetArrowSize(2);
//--- Get the pointer to the up arrow button and set the colors of its various states for it
   CArrowUpButton *bu=this.GetArrowButtonUp();
   if(bu!=NULL)
     {
      bu.SetBackgroundColor(CLR_DEF_CONTROL_SCROLL_BAR_BUTT_COLOR,true);
      bu.SetBackgroundColorMouseDown(CLR_DEF_CONTROL_SCROLL_BAR_BUTT_MOUSE_DOWN);
      bu.SetBackgroundColorMouseOver(CLR_DEF_CONTROL_SCROLL_BAR_BUTT_MOUSE_OVER);
      bu.SetForeColor(CLR_DEF_CONTROL_SCROLL_BAR_BUTT_FORE_COLOR,true);
      bu.SetForeColorMouseDown(CLR_DEF_CONTROL_SCROLL_BAR_BUTT_FORE_MOUSE_DOWN);
      bu.SetForeColorMouseOver(CLR_DEF_CONTROL_SCROLL_BAR_BUTT_FORE_MOUSE_OVER);
     }
//--- Get the pointer to the down arrow button and set the colors of its various states for it
   CArrowDownButton *bd=this.GetArrowButtonDown();
   if(bd!=NULL)
     {
      bd.SetBackgroundColor(CLR_DEF_CONTROL_SCROLL_BAR_BUTT_COLOR,true);
      bd.SetBackgroundColorMouseDown(CLR_DEF_CONTROL_SCROLL_BAR_BUTT_MOUSE_DOWN);
      bd.SetBackgroundColorMouseOver(CLR_DEF_CONTROL_SCROLL_BAR_BUTT_MOUSE_OVER);
      bd.SetForeColor(CLR_DEF_CONTROL_SCROLL_BAR_BUTT_FORE_COLOR,true);
      bd.SetForeColorMouseDown(CLR_DEF_CONTROL_SCROLL_BAR_BUTT_FORE_MOUSE_DOWN);
      bd.SetForeColorMouseOver(CLR_DEF_CONTROL_SCROLL_BAR_BUTT_FORE_MOUSE_OVER);
     }
//--- Get the pointer to the capture area object and set the colors of its various states for it
   CScrollBarThumb *th=this.GetThumb();
   if(th!=NULL)
     {
      th.SetBackgroundColor(CLR_DEF_CONTROL_SCROLL_BAR_THUMB_COLOR,true);
      th.SetBorderColor(CLR_DEF_CONTROL_SCROLL_BAR_THUMB_BORDER_COLOR,true);
      th.SetBackgroundColorMouseDown(CLR_DEF_CONTROL_SCROLL_BAR_THUMB_MOUSE_DOWN);
      th.SetBackgroundColorMouseOver(CLR_DEF_CONTROL_SCROLL_BAR_THUMB_MOUSE_OVER);
      th.SetForeColor(CLR_DEF_CONTROL_SCROLL_BAR_THUMB_FORE_COLOR,true);
      th.SetForeColorMouseDown(CLR_DEF_CONTROL_SCROLL_BAR_THUMB_FORE_MOUSE_DOWN);
      th.SetForeColorMouseOver(CLR_DEF_CONTROL_SCROLL_BAR_THUMB_FORE_MOUSE_OVER);
     }
  }
//+------------------------------------------------------------------+
//| Calculate the capture area size                                  |
//+------------------------------------------------------------------+
int CScrollBarVertical::CalculateThumbAreaSize(void)
  {
   return 0;
  }
//+------------------------------------------------------------------+
//| Timer                                                            |
//+------------------------------------------------------------------+
void CScrollBarVertical::OnTimer(void)
  {

  }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CScrollBarVertical::OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- Adjust subwindow Y shift
   CGCnvElement::OnChartEvent(id,lparam,dparam,sparam);
//--- If the event ID is an object movement
   if(id==WF_CONTROL_EVENT_MOVING)
     {
      //--- Get the pointer to the capture area object
      CScrollBarThumb *thumb=this.GetThumb();
      if(thumb==NULL)
         return;
      //--- Get the pointer to the button object with the up arrow
      CArrowUpButton *buttu=this.GetArrowButtonUp();
      if(buttu==NULL)
         return;
      //--- Get the pointer to the button object with the down arrow
      CArrowDownButton *buttd=this.GetArrowButtonDown();
      if(buttd==NULL)
         return;
      //--- Declare the variables for the coordinates of the capture area
      int x=(int)lparam;
      int y=(int)dparam;
      //--- Set the X coordinate equal to the X coordinate of the control element
      x=this.CoordX()+this.BorderSizeLeft();
      //--- Adjust the Y coordinate so that the capture area does not go beyond the control, taking into account the arrow buttons
      if(y<buttu.BottomEdge())
        y=buttu.BottomEdge();
      if(y>buttd.CoordY()-thumb.Height())
        y=buttd.CoordY()-thumb.Height();
      //--- If the capture area object is shifted by the calculated coordinates
      if(thumb.Move(x,y,true))
        {
         //--- set the object relative coordinates
         thumb.SetCoordXRelative(thumb.CoordX()-this.CoordX());
         thumb.SetCoordYRelative(thumb.CoordY()-this.CoordY());
         ::ChartRedraw(this.ChartID());
        }
     }
  }
//+------------------------------------------------------------------+
