Discussion of article "Graphical Interfaces X: Sorting, rebuilding the table and controls in the cells (build 11)" - page 7

 
Anatoli Kazharski:
I must have inserted the wrong example in the article. In any case, correct it for your tasks as you need.

I'm not copying your code, I'm interested in the work of the SetImages method itself, is it necessary to put pictures in each cell if you use them in any column of the table, or is it a mistake in your example and you need to insert them only where you use them?
 
Konstantin:

I'm not copying your code, I'm interested in the work of the SetImages method itself, is it necessary to put pictures into each cell if you use them in any column of the table, or is it a mistake in your example and you should only insert them where you use them?

As far as I understand, you need to insert pictures only in the cells of the first column.

Try it like this:

//+------------------------------------------------------------------+
//| Initialising the table|
//+------------------------------------------------------------------+
void CMainPanel::InitializingTable(void)
  {
//--- Array of header names
   string text_headers[COLUMNS1_TOTAL]={"Symbol","Bid","Ask","!","Time"};
//--- Array of characters
   string text_str = "MFON SBER SBERP GAZP TATN LKOH ROSN NVTK SNGS SNGSP VTBR MOEX AFKS IRAO "
                     "AFLT FEES ALRS MAGN NLMK CHMF GMKN HYDR TATNP YNDX RTKM MGNT MTSS";
   string text_array[];
   int _size = CreateArray(text_str, text_array); 
//--- Array of pictures
   string image_array[3]=
     {
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\circle_gray.bmp",
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_up.bmp",
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_down.bmp"
     };
//---
   for(int c=0; c<COLUMNS1_TOTAL; c++)
     {
      //--- Set the header names
      m_canvas_table.SetHeaderText(c,text_headers[c]);
      //---
      for(int r=0; r<ROWS1_TOTAL; r++)
        {
         //--- Set pictures and character names in the first column
         if(c<1)
            {
             m_canvas_table.SetImages(c,r,image_array);
             m_canvas_table.SetValue(c,r,text_array[r]);
            }
         //--- In all other columns for all cells the default value and without pictures
         else
            m_canvas_table.SetValue(c,r,"-");
        }
     }
  }
 
Anatoli Kazharski:

As far as I understand, you need to insert images only in the cells of the first column.

Try this:


))))) so there is still a typo in the method? I went about this way.

And what is the best way to optimise the load on the calculated capacities. There are data that are counted once a period (for example, M5), the data are displayed in a table from OnTimer. The size of the rows on each recalculation is not guaranteed to be equal to the last calculation. I see two options so far:
1. After each recalculation delete all rows and create the necessary number of rows. In between recalculations the data is simply updated.

2. After each recalculation, we update the data in the existing rows of the table, if there are not enough rows, we add new ones, if there are more rows than data, we delete the ones we don't need.

Which of these options is more acceptable for a table based on CCanvasTable?

 
Konstantin:

...

Which of these options is more acceptable for a table based on CCanvasTable?

I won't be able to answer that right away. Try to make tests with time measurements(GetTickCount() or GetMicrosecondCount()) or test in profiling mode.
 
Anatoli Kazharski:
I won't be able to give you an immediate answer. Try making tests with time measurements(GetTickCount() or GetMicrosecondCount()) or test in profiling mode.
for some reason the picture is inserted only in the column with index 0, it is not inserted in other columns, is it a peculiarity or something wrong?
 
Konstantin:
for some reason the picture is inserted only in the column with index 0, in other columns it is not put, is it a peculiarity or something wrong?

And what result do you want to get? Describe in detail.

And what is the problem to do it yourself? All the necessary methods are provided for this.

P.S. Show screenshots and code to better understand what you need.

 
Anatoli Kazharski:

And what result do you want? Describe it in detail.

And what's the problem with doing it yourself? All the necessary methods are provided for this.

P.S. Show screenshots and code to better understand what you need.


If I use your example, I change the index from 0 to 1:

void CProgram::UpdateTable(void)
  {
   MqlDateTime check_time;
   ::TimeToStruct(::TimeTradeServer(),check_time);
//--- Exit if it's Saturday or Sunday
   if(check_time.day_of_week==0 || check_time.day_of_week==6)
      return;
//---
   for(uint c=0; c < m_canvas_table.ColumnsTotal(); c++)
     {
      for(uint r=0; r < m_canvas_table.RowsTotal(); r++)
        {
         //--- For which character we get data
         string symbol = m_canvas_table.GetValue(0, r);
         //--- Get the data of the last two ticks
         MqlTick ticks[];
         if(::CopyTicks(symbol, ticks, COPY_TICKS_ALL, 0, 2) < 2)
            continue;
         //--- Set the array as a time series
         ::ArraySetAsSeries(ticks, true);
         //--- Symbol column - Symbol. Let's determine the price direction.
         if(c==1)
           {
            int index=0;
            //--- If prices have not changed
            if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
               index=0;
            //--- If the Bid price has changed upwards
            else if(ticks[0].bid>ticks[1].bid)
               index=1;
            //--- If the Bid price has changed downwards
            else if(ticks[0].bid<ticks[1].bid)
               index=2;
            //--- Set the corresponding picture
            m_canvas_table.ChangeImage(c,r,index,true);
           }
         else
           {
            //--- Price difference column - Spread (!)
            if(c==3)
              {
               //--- Get and set the spread size in pips
               int spread=(int)::SymbolInfoInteger(symbol,SYMBOL_SPREAD);
               m_canvas_table.SetValue(c,r,string(spread),true);
               continue;
              }
            //--- Get the number of decimal places
            int digit=(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS);
            //--- Price column Bid
            if(c==1)
              {
               m_canvas_table.SetValue(c,r,::DoubleToString(ticks[0].bid,digit));
               //--- If the price has changed, set the colour corresponding to the direction
               if(ticks[0].bid!=ticks[1].bid)
                  m_canvas_table.TextColor(c,r,(ticks[0].bid<ticks[1].bid)? clrRed : clrBlue,true);
               //---
               continue;
              }
            //--- Ask price column
            if(c==2)
              {
               m_canvas_table.SetValue(c,r,::DoubleToString(ticks[0].ask,digit));
               //--- If the price has changed, set the colour corresponding to the direction
               if(ticks[0].ask!=ticks[1].ask)
                  m_canvas_table.TextColor(c,r,(ticks[0].ask<ticks[1].ask)? clrRed : clrBlue,true);
               //---
               continue;
              }
            //--- Column of the last arrival time of the symbol prices
            if(c==4)
              {
               long   time     =::SymbolInfoInteger(symbol,SYMBOL_TIME);
               string time_msc =::IntegerToString(ticks[0].time_msc);
               int    length   =::StringLen(time_msc);
               string msc      =::StringSubstr(time_msc,length-3,3);
               string str      =::TimeToString(time,TIME_MINUTES|TIME_SECONDS)+"."+msc;
               //---
               color clr=clrBlack;
               //--- If prices have not changed
               if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
                  clr=clrBlack;
               //--- If the Bid price has changed upwards
               else if(ticks[0].bid>ticks[1].bid)
                  clr=clrBlue;
               //--- If the Bid price has changed downwards
               else if(ticks[0].bid<ticks[1].bid)
                  clr=clrRed;
               //--- Set the value and colour of the text
               m_canvas_table.SetValue(c,r,str);
               m_canvas_table.TextColor(c,r,clr,true);
               continue;
              }
           }
        }
     }

   int _height = int(m_chart.HeightInPixels(0) * .30);
   m_canvas_table.AutoYResizeBottomOffset(_height);

//--- Update table
   m_canvas_table.UpdateTable();
  }

the icons should move to the column with index 1, i.e. the second one, but it doesn't happen. The example is taken from TestLibrary10.mqh. I have not found any methods for positioning the figures, if there are any, please tell me.

 
In general, I can not understand the principle of loading pictures into the cells of the table. In the example TestLibrary09.mqh drawings are loaded in different columns, and in the example TestLibrary10.mqh only in the column with index 0, when set in other columns drawings are not loaded. Can you tell me what is the subtlety there?
 
Konstantin:
In general, I can not understand the principle of loading pictures into the cells of the table. In the example TestLibrary09.mqh drawings are loaded in different columns, and in the example TestLibrary10.mqh only in the column with index 0, when set in other columns drawings are not loaded. Can you tell me what is the subtlety there?

For each cell of the table, which should be pictures, you need its own array of pictures. If the cell with the type CELL_BUTTON, then a minimum of one picture per cell is enough, if the type CELL_CHECKBOX, then a minimum of two.

For example:

The picture with index 0 - corresponds to the "pressed" state of the checkbox (button), the other indices correspond to the "selected" state of the checkbox (button).

(not finished, but it will do for understanding):

MetaTrader trading platform screenshots

EURUSD, M1, 2017.04.21

MetaQuotes Software Corp., MetaTrader 4, Demo

EURUSD, M1, 2017.04.21, MetaQuotes Software Corp., MetaTrader 4, Demo

There is only one column in the right table with the list of symbols, and it is of type CELL_CHECKBOX - it requires an image array size of at least 2:
arr_chk[2]; arr_chk[0]=m_img_chk_off; (image of a checkbox with the checkbox unchecked) arr_chk[1]=m_img_chk_on; (image of a checkbox with the checkbox checked)


In the main table:

Cell 0 contains the graph opening picture - it has type CELL_BUTTON, you can have an array of images with dimension 1: arr_img0[1]; arr_img0[0]=m_image_graph;

Cell 8 contains the Buy opening picture - its type is CELL_BUTTON, the image array can be of dimension 1: arr_img8[1]; arr_img8[0]=m_image_buy;

Cell 9 contains the Sell opening picture - it has type CELL_BUTTON, the image array can be of dimension 1: arr_img9[1]; arr_img9[0]=m_image_sell;

After creating the table, you can initialise it with the required values and set the required cell types and set your own image arrays for them.


 
Artyom Trishkin:

For each cell of the table, which should contain pictures, you need its own array of pictures. If the cell is of type CELL_BUTTON, then a minimum of one picture per cell is enough, if the type is CELL_CHECKBOX, then a minimum of two. The picture with index 0 corresponds to the "pressed" state of the checkbox (button), the other indices correspond to the "selected" state of the checkbox (button).

For example (not finished, but it will do for understanding):

In the right table with the list of symbols, there is only one column, and it is of type CELL_CHECKBOX - it requires an image array size of at least 2:
arr_chk[2]; arr_chk[0]=m_img_chk0; arr_chk[1]=m_img_chk1;


In the main table:

Cell 0 contains the graph opening picture - it has type CELL_BUTTON, you can have an array of images with dimension 1: arr_img0[1]; arr_img0[0]=m_image_graph;

Cell 8 contains the Buy opening picture - its type is CELL_BUTTON, the image array can be of dimension 1: arr_img8[1]; arr_img8[0]=m_image_buy;

Cell 9 contains the Sell opening picture - it has type CELL_BUTTON, the image array can be of dimension 1: arr_img9[1]; arr_img9[0]=m_image_sell;

Once the table is created, you can initialise it with the desired values and set the desired cell types and set your image arrays for them.


I really do not understand what the problem is )) in the first screen changed to the column with index 1 images disappeared, and in the second screen back to the column with index 0, the images appeared. This is all on the example code TestLibrary10. mqh

Here are the methods of creating the table:

bool CProgram::CreateCanvasTable(const int x_gap,const int y_gap)
  {
#define  COLUMNS1_TOTAL 5
#define  ROWS1_TOTAL    27
//--- Save the pointer to the form
   m_canvas_table.WindowPointer(m_window);
//--- Array of column widths
   int width[COLUMNS1_TOTAL]={75, 60, 60, 60, 75};
//--- Array of text indentation in columns on X axis
   int text_x_offset[COLUMNS1_TOTAL];
   ::ArrayInitialize(text_x_offset,5);
   text_x_offset[0]=25;
//--- Array of text alignment in columns
   ENUM_ALIGN_MODE align[COLUMNS1_TOTAL];
   ::ArrayInitialize(align,ALIGN_RIGHT);
   align[0]=ALIGN_LEFT;
//--- Set properties before creation
   m_canvas_table.XSize(345);
   m_canvas_table.YSize(289);
   m_canvas_table.TableSize(COLUMNS1_TOTAL, ROWS1_TOTAL);
   m_canvas_table.TextAlign(align);
   m_canvas_table.TextXOffset(text_x_offset);
   m_canvas_table.ColumnsWidth(width);
   m_canvas_table.TextXOffset(5);
   m_canvas_table.TextYOffset(4);
   m_canvas_table.CellYSize(20);
   //m_canvas_table.ImageXOffset(8);//
   //m_canvas_table.ImageYOffset(6);//
   m_canvas_table.ShowHeaders(true);
   m_canvas_table.HeaderYSize(30);
   m_canvas_table.HeadersColor(C'255,244,213');
   m_canvas_table.CellColorHover(C'255,244,213');
   m_canvas_table.LightsHover(true);
   m_canvas_table.SelectableRow(true);
   m_canvas_table.ColumnResizeMode(true);
   m_canvas_table.IsZebraFormatRows(clrWhiteSmoke);
   //m_canvas_table.AutoXResizeMode(true);
   m_canvas_table.AutoXResizeRightOffset(1);
   m_canvas_table.AutoYResizeMode(true);
   int _height = int(m_chart.HeightInPixels(0) * .30);
   m_canvas_table.AutoYResizeBottomOffset(/*25 + */_height);
//--- Fill the table with data
   InitializingTable();
//--- Create a control
   if(!m_canvas_table.CreateTable(m_chart_id,m_subwin,x_gap,y_gap))
      return(false);
//--- Add the object to the common array of object groups
   CWndContainer::AddToElementsArray(0,m_canvas_table);
   return(true);
  }

is initialisation:

void CProgram::InitializingTable(void)
  {
//--- Array of header names
   string text_headers[COLUMNS1_TOTAL]={"Symbol","Bid","Ask","!","Time"};
//--- Array of characters
   //string text_array[25]=
   // {
   // "AUDUSD", "GBPUSD", "EURUSD", "USDCAD", "USDCHF", "USDJPY", "NZDUSD", "USDSEK", "USDHKD", "USDMXN",
   // "USDZAR", "USDTRY", "GBPAUD", "AUDCAD", "CADCHF", "EURAUD", "GBPCHF", "GBPJPY", "NZDJPY", "AUDJPY",
   // "EURJPY", "EURCHF", "EURGBP", "AUDCHF", "CHFJPY"
   // };
   string text_str = "MFON SBER SBERP GAZP TATN LKOH ROSN NVTK SNGS SNGSP VTBR MOEX AFKS IRAO "
                     "AFLT FEES ALRS MAGN NLMK CHMF GMKN HYDR TATNP YNDX RTKM MGNT MTSS";
   string text_array[];
   int _size = CreateArray(text_str, text_array); 
//--- Array of pictures
   string image_array[3]=
     {
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\circle_gray.bmp",//circle_gray_t32.bmp",
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_up.bmp",
      "::Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_down.bmp"
     };
//---
   for(int c=0; c<COLUMNS1_TOTAL; c++)
     {
      //--- Set the header names
      m_canvas_table.SetHeaderText(c,text_headers[c]);
      //---
      for(int r=0; r<ROWS1_TOTAL; r++)
        {
         //--- Set the pictures
         if(c == 1) {
            m_canvas_table.CellType(c, r, CELL_BUTTON);
            m_canvas_table.SetImages(c,r,image_array);
         }
         //--- Set character names
         if(c<1)
            m_canvas_table.SetValue(c,r,text_array[r]);
         //--- Default value for all cells
         else
            m_canvas_table.SetValue(c,r,"-");
        }
     }
  }

this is update:

void CProgram::UpdateTable(void)
  {
   MqlDateTime check_time;
   ::TimeToStruct(::TimeTradeServer(),check_time);
//--- Exit if it's Saturday or Sunday
   if(check_time.day_of_week==0 || check_time.day_of_week==6)
      return;
//---
   for(uint c=0; c < m_canvas_table.ColumnsTotal(); c++)
     {
      for(uint r=0; r < m_canvas_table.RowsTotal(); r++)
        {
         //--- For which character we get data
         string symbol = m_canvas_table.GetValue(0, r);
         //--- Get the data of the last two ticks
         MqlTick ticks[];
         if(::CopyTicks(symbol, ticks, COPY_TICKS_ALL, 0, 2) < 2)
            continue;
         //--- Set the array as a time series
         ::ArraySetAsSeries(ticks, true);
         //--- Symbol column - Symbol. Let's determine the price direction.
         if(c==1)
           {
            int index=0;
            //--- If prices have not changed
            if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
               index=0;
            //--- If the Bid price has changed upwards
            else if(ticks[0].bid > ticks[1].bid)
               index=1;
            //--- If the Bid price has changed downwards
            else if(ticks[0].bid < ticks[1].bid)
               index=2;
            //--- Set the corresponding picture
            m_canvas_table.ChangeImage(c,r,index,true);
           }
         else
           {
            //--- Price difference column - Spread (!)
            if(c==3)
              {
               //--- Get and set the spread size in pips
               int spread=(int)::SymbolInfoInteger(symbol,SYMBOL_SPREAD);
               m_canvas_table.SetValue(c,r,string(spread),true);
               continue;
              }
            //--- Get the number of decimal places
            int digit=(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS);
            //--- Price column Bid
            if(c==1)
              {
               m_canvas_table.SetValue(c,r,::DoubleToString(ticks[0].bid,digit));
               //--- If the price has changed, set the colour corresponding to the direction
               if(ticks[0].bid!=ticks[1].bid)
                  m_canvas_table.TextColor(c,r,(ticks[0].bid<ticks[1].bid)? clrRed : clrBlue,true);
               //---
               continue;
              }
            //--- Ask price column
            if(c==2)
              {
               m_canvas_table.SetValue(c,r,::DoubleToString(ticks[0].ask,digit));
               //--- If the price has changed, set the colour corresponding to the direction
               if(ticks[0].ask!=ticks[1].ask)
                  m_canvas_table.TextColor(c,r,(ticks[0].ask<ticks[1].ask)? clrRed : clrBlue,true);
               //---
               continue;
              }
            //--- Column of the last arrival time of the symbol prices
            if(c==4)
              {
               long   time     =::SymbolInfoInteger(symbol,SYMBOL_TIME);
               string time_msc =::IntegerToString(ticks[0].time_msc);
               int    length   =::StringLen(time_msc);
               string msc      =::StringSubstr(time_msc,length-3,3);
               string str      =::TimeToString(time,TIME_MINUTES|TIME_SECONDS)+"."+msc;
               //---
               color clr=clrBlack;
               //--- If prices have not changed
               if(ticks[0].ask==ticks[1].ask && ticks[0].bid==ticks[1].bid)
                  clr=clrBlack;
               //--- If the Bid price has changed upwards
               else if(ticks[0].bid>ticks[1].bid)
                  clr=clrBlue;
               //--- If the Bid price has changed downwards
               else if(ticks[0].bid<ticks[1].bid)
                  clr=clrRed;
               //--- Set the value and colour of the text
               m_canvas_table.SetValue(c,r,str);
               m_canvas_table.TextColor(c,r,clr,true);
               continue;
              }
           }
        }
     }

   int _height = int(m_chart.HeightInPixels(0) * .30);
   m_canvas_table.AutoYResizeBottomOffset(_height);

//--- Update table
   m_canvas_table.UpdateTable();
  }
highlighted changed from 0 to 1, i.e. changed the picture insertion in the column from number 0 to number 1, where is the error here?
Files:
07.png  163 kb
00.png  161 kb