Discussing the article: "Making a dashboard to display data in indicators and EAs" - page 4

 
Denis Kirichenko #:
Move(int x, int y)

There is a bug somewhere. You need to print (or look in the debugger, but it often doesn't work) the coordinate and size values.

Here is the logic in the comments:

   //--- If the panel height is not greater than the window height size
   if(!this.m_higher_wnd)
     {
      if(y+h>this.m_chart_h-2)
         y=this.m_chart_h-h-2;
      if(y<1)
         y=1;
     }
   //--- If the height panel is not within the height window size
   else
     {
      //--- Keep the panel below the top edge of the window with a gap of 1 pixel
      if(y>1)
         y=1;
      //--- Keep the panel from falling below the bottom edge of the window with a gap of 1 pixel
      if(y<this.m_chart_h-h-2)
         y=this.m_chart_h-h-2;
     }
 
Denis Kirichenko #:
When trying to move the panel after changing the chart size, it constantly corrects the coordinates and does not let you move the panel window freely...

Most likely the value of this.m_higher_wnd variable is not relevant in the Move() method. These values are set in the event handler:

//+------------------------------------------------------------------+
//| Event handler|
//+------------------------------------------------------------------+
void CDashboard::OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- If a graphical object is created
   if(id==CHARTEVENT_OBJECT_CREATE)
     {
      this.BringToTop();
      ::ObjectSetInteger(this.m_chart_id,sparam,OBJPROP_SELECTED,true);
     }
//--- If the schedule is changed
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      //--- Get the number of the chart subwindow, if it is not the main window (the number may change when deleting the window of any indicator)
      if(this.m_wnd!=0)
         this.m_wnd=this.GetSubWindow();
      //--- Get the new chart dimensions
      int w=(int)::ChartGetInteger(this.m_chart_id,CHART_WIDTH_IN_PIXELS,this.m_wnd);
      int h=(int)::ChartGetInteger(this.m_chart_id,CHART_HEIGHT_IN_PIXELS,this.m_wnd);
      //--- Determine whether the panel size is outside the chart window
      this.m_higher_wnd=this.HigherWnd();
      this.m_wider_wnd=this.WiderWnd();
      //--- If the chart height has changed - adjust the vertical position of the panel
      if(this.m_chart_h!=h)
        {
         this.m_chart_h=h;
         int y=this.m_y;
         if(this.m_y+this.m_h>h-1)
            y=h-this.m_h-1;
         if(y<1)
            y=1;
         this.Move(this.m_x,y);
        }
      //--- If the chart width has changed - adjust the horizontal position of the panel
      if(this.m_chart_w!=w)
        {
         this.m_chart_w=w;
         int x=this.m_x;
         if(this.m_x+this.m_w>w-1)
            x=w-this.m_w-1;
         if(x<1)
            x=1;
         this.Move(x,this.m_y);
        }
     }

It is quite possible that somewhere here the oversize flags are not set correctly when the chart window is expanded.

If you write these lines

this.m_higher_wnd=this.HigherWnd();
this.m_wider_wnd=this.WiderWnd();

at the very beginning of the Move() method - to force setting of correct values at each mouse movement, will the bug disappear? If it does, it means that the matter is in the values of these variables, and you need to look in the event handler to see why they do not get their values when the window is expanded. Well, if everything is normal there, then you need to print the Move() method to find the error.

 

The bug has disappeared. I made these changes to the CDashboard::OnChartEvent() method:


//--- If the schedule is changed
   if(id == CHARTEVENT_CHART_CHANGE)
     {
      //--- Get the number of the chart subwindow, if it is not the main window (the number may change when deleting the window of any indicator)
      if(m_wnd != 0)
         m_wnd = GetSubWindow();
      //
      long value;
      // reset the error value
      ::ResetLastError();
      // get the value of the property
      if(!::ChartGetInteger(m_chart_id, CHART_BRING_TO_TOP, m_wnd, value))
        {
         //--- output the error message to the "Experts" log.
         Print(__FUNCTION__ + ", Error Code = ", ::GetLastError());
         return;
        }
      // if it is not displaying the graph on top of all others - exit
      if(value == 0)
         return;
      //--- Get the new chart dimensions
      int w = (int)::ChartGetInteger(m_chart_id, CHART_WIDTH_IN_PIXELS, m_wnd);
      int h = (int)::ChartGetInteger(m_chart_id, CHART_HEIGHT_IN_PIXELS, m_wnd);
      //--- Determine whether the panel size is outside the chart window
      //m_higher_wnd = HigherWnd();
      //m_wider_wnd = WiderWnd();
      //--- If the chart height has changed - adjust the vertical position of the panel
      if(m_chart_h != h)
        {
         m_chart_h = h;
         m_higher_wnd = HigherWnd(); // added
         int y = m_y;
         if(m_y + m_h > h - 1)
            y = h - m_h - 1;
         if(y < 1)
            y = 1;
         Move(m_x, y);
        }
      //--- If the chart width has changed - adjust the horizontal position of the panel
      if(m_chart_w != w)
        {
         m_chart_w = w; 
         m_wider_wnd = WiderWnd(); // added
         int x = m_x;
         if(m_x + m_w > w - 1)
            x = w - m_w - 1;
         if(x < 1)
            x = 1;
         Move(x, m_y);
        }
     }


In order not to constantly load the CDashboard:: Move() method, I added checking for oversize flags in those blocks where the width and height of the chart window are directly changed.


 
Denis Kirichenko #:

The bug has disappeared. I made these changes to the CDashboard::OnChartEvent() method:

In order not to constantly load the CDashboard:: Move() method, I added checking for oversize flags in those blocks where the width and height of the chart window are directly changed.

Thanks. I'll put it in.