Discussion of article "Graphical Interfaces X: Text selection in the Multiline Text box (build 13)" - page 11

 
Anatoli Kazharski:

Add tabs before creating an element. Refer to the examples in the articles about this or that element. If something is not mentioned, it means that this feature does not exist yet.

Adding and deleting after an element is created works now only in lists and tables.

I.e. in this class the CreateTabs method is fundamental for creating tabs? And will it be correct when changing the number of tabs, if we use the Delete method and after it use the CreateTabs method? Or is it necessary to specify all properties again after the Delete method as at the initial creation?
 
Konstantin:
I.e. in this class the CreateTabs method is fundamental for creating tabs? When changing the number of tabs, would it be correct to use the Delete method and then use the CreateTabs method after it? Or is it necessary to specify all properties again after the Delete method as at the initial creation?

Yes. We specify the properties first and then create the item.

At the moment there is no mechanism for correct deletion of elements at runtime. They will remain in the general list of elements. But try it as you described it in your question. I haven't tested this way yet.

 
Anatoli Kazharski:

Yes. We first specify the properties and then create the element.

At the moment there is no mechanism for correct deletion of elements at runtime. They will remain in the general list of elements. But try it as you described it in your question. I haven't tested this way yet.

))) I am already trying it, if everything goes correctly, I will post an example.
 

this is how it works:

#ifndef __TBLTABS_MQH__
#define __TBLTABS_MQH__

#include "..\\..\\..\\v1.00\\lib\\define.mqh"

#include <Arrays\List.mqh>
#include <EasyAndFastGUI\WndEvents.mqh>

//+------------------------------------------------------------------+
class CTblTabs
  {
private:
   int      m_x;
   int      m_y;
   long     m_chart_id;
   int      m_subwin;
   string   m_text[];
   int      m_width[];
   CTabs    m_tabs;
   CWindow  *m_form;

public:
                     CTblTabs(void);
                    ~CTblTabs(void);
   bool              Create(CWindow &a_form,const long a_chart_id,const int a_subwin,     // object creation
                              const int a_x,const int a_y);
   void              OnLinkProgram(CList &a_pair);                                        // communication with the programme
   CTabs*            GetTbl(void) { return &m_tabs; }

private:
   void              UpdateTabs(CList &a_pair,CTabs &a_tabs,string &a_text[],int &a_width[]);   // update table values
   bool              ReInit(CWindow &a_form,CList &a_pair,CTabs &a_tabs,string &a_text[],       // reinitialisation of object tabs
                              int &a_width[],const long a_chart_id,const int a_subwin,const int a_x,const int a_y);
  };
//+------------------------------------------------------------------+
/*!
 \brief Designer
*/
CTblTabs::CTblTabs(void) : m_x(0), m_y(0), m_chart_id(0), m_subwin(0), m_form(NULL) { }
/*!
 \brief Destructor
*/
CTblTabs::~CTblTabs(void) {
   m_form = NULL;
}
/*!
 \brief Creating an object
 \param CWindow &a_form - form object
 \param const long a_chart_id - chart ID
 \param const int a_subwin - chart subwindow
 \param const int a_x - X coordinate
 \param const int a_y - Y coordinate
 \return true if successful, otherwise false
*/
bool CTblTabs::Create(CWindow &a_form,const long a_chart_id,const int a_subwin,const int a_x,const int a_y) {
   m_x = a_x;
   m_y = a_y;
   m_chart_id = a_chart_id;
   m_subwin   = a_subwin;
   m_form     = &a_form;

   //--- arrays with text and width for tabs
   //::ArrayResize(m_text, 1);
   //m_text[0] = "NULL_NULL";
   //::ArrayResize(m_width, 1);
   //m_width[0] = 65;

   m_tabs.WindowPointer(a_form);       // save the pointer to the form

   //--- coordinates
   int _x = a_form.X() + m_x;
   int _y = a_form.Y() + m_y;

   //--- dimensions
   m_tabs.XSize(400);
   m_tabs.YSize(200);

   //--- properties
   m_tabs.TabYSize(20);
   m_tabs.PositionMode(TABS_TOP);
   m_tabs.AutoXResizeMode(true);
   m_tabs.AutoYResizeMode(true);
   m_tabs.AutoXResizeRightOffset(200);
   m_tabs.AutoYResizeBottomOffset(23);
   m_tabs.TabBorderColor(clrLightSteelBlue);
   m_tabs.SelectedTab((m_tabs.SelectedTab() == WRONG_VALUE) ? 0 : m_tabs.SelectedTab());


   //--- add tabs with the specified properties
   //for(int i = 0, _size = ArraySize(m_text); i < _size; ++i)
   // m_tabs.AddTab(m_text[i], m_width[i]);

   //--- create a control
   //if(!m_tabs.CreateTabs(a_chart_id, a_subwin, _x, _y))
   //   return false;

//---
   return true;
}
/*!
 \brief Connection with the programme
 \param CList &a_pair - pointer to the list of trading pairs with signals
*/
void CTblTabs::OnLinkProgram(CList &a_pair) {
   if(a_pair.Total() != m_tabs.TabsTotal())
      this.ReInit(m_form, a_pair, m_tabs, m_text, m_width, m_chart_id, m_subwin, m_x, m_y);
   else
      this.UpdateTabs(a_pair, m_tabs, m_text, m_width);
}
//+------------------------------------------------------------------+
/*!
 \brief Update tab values
 \param CList &a_pair - pointer to the list of trading pairs with signals
 \param CTabs &a_tabs - table object
 \param string &a_text[] - array with tabs name
 \param int &a_width[] - array with tabs width size
*/
void CTblTabs::UpdateTabs(CList &a_pair,CTabs &a_tabs,string &a_text[],int &a_width[]) {
   int _total = a_tabs.TabsTotal();
   //--- decompose the data into a table
   int _count = 0;
   for(CWrapUnitPair *_unit = a_pair.GetFirstNode(); _unit != NULL; _count++, _unit = a_pair.GetNextNode())
      a_tabs.Text(_count, _unit.data_tt[0].ticker + " " + _unit.data_tt[1].ticker);

}
/*!
 \brief Reinitialisation of object tabs
 \param CWindow &a_form - form object
 \param CList &a_pair - pointer to the list of trading pairs with signals
 \param CTabs &a_tabs - table object
 \param string &a_text[] - array with the name of tabs
 \param int &a_width[] - array with tabs width size
 \param const long a_chart_id - chart ID
 \param const int a_subwin - chart subwindow
 \param const int a_x - X coordinate
 \param const int a_y - Y coordinate
 \return true if successful, otherwise false
*/
bool CTblTabs::ReInit(CWindow &a_form,CList &a_pair,CTabs &a_tabs,string &a_text[],int &a_width[],const long a_chart_id,
                                                                                  const int a_subwin,
                                                                                  const int a_x,
                                                                                  const int a_y) {

   a_tabs.Delete();     // clear the tabs from the object

   //--- reinitialise arrays of values
   int _total = a_pair.Total();
   ::ArrayResize(a_text, _total);
   ::ArrayResize(a_width, _total);

   //--- fill the arrays with tab names
   int _count = 0;
   for(CWrapUnitPair *_unit = a_pair.GetFirstNode(); _unit != NULL; _count++, _unit = a_pair.GetNextNode()) {
      a_text[_count]  = _unit.data_tt[0].ticker + " " + _unit.data_tt[1].ticker;
      a_width[_count] = 65;
   }

   //--- add tabs with the specified properties
   for(int i = 0, _size = ArraySize(m_text); i < _size; ++i)
      a_tabs.AddTab(a_text[i], a_width[i]);

   //--- coordinates
   int _x = a_form.X() + a_x;
   int _y = a_form.Y() + a_y;

   //--- create a control
   if(!a_tabs.CreateTabs(a_chart_id, a_subwin, _x, _y))
      return false;
//---
   return true;
}
//+------------------------------------------------------------------+

#endif // __TBLTABS_MQH__

I have highlighted in colour what is no longer needed in the class creation method, as it is essentially used in the ReInit method .

All event and interaction mechanisms are described in the main form class of the programme.


 
Konstantin:

that's how it works:

Thanks for the example. Interesting.

 
Anatoli Kazharski:

Thanks for the example. Interesting.


I found one bug - if there are no tabs, when changing the size of the chart (form), the programme crashes with the error array out of range in 'Tabs.mqh' (821,21)

 
Konstantin:

found one bug - if there are no tabs, then when changing the size of the chart (form), the programme crashes with the error array out of range in 'Tabs.mqh' (821,21).

There will be a fix in the next update.
 

When creating objects (form elements), the CWndContainer::AddToElementsArray(0, m_object); method is used, is there any mechanism to correctly remove a given object from this container?

This is required when creating / deleting charts, when using the above mechanism of adding / deleting tabs.

 
Konstantin:

When creating objects (form elements), the CWndContainer::AddToElementsArray(0, m_object); method is used, is there any mechanism to correctly remove a given object from this container?

This is required when creating / deleting charts, when using the above mechanism of adding / deleting tabs.

This has not been implemented yet.

 
Anatoli Kazharski:

This is not implemented yet.

it would be more logical to make deletion at the request of the class user, because working with objects in dynamics animates the interface more, for my task I will enter the number of charts by the number of ticker pairs, but since I have 702 ticker pairs based on 27 tickers, it is not difficult to calculate what brakes will be if you go to another market where there are many more tickers ))

by the way, I will also check how much memory will be consumed by such a number of ticker pairs ))