Creating a graphic library from scratch - page 14

 
Try to make a full-fledged window. Like a Windows form. You can do it without dynamism, but since you've partially implemented it, I think you'll get a Windows-like "rubber" window.
 
Реter Konow:
Try to make a full-fledged window. Like a Windows form. You can do it without dynamism, but since you have partially implemented it, I think you'll get a Windows-like "rubber" window.
The hardest part will be drawing the buttons :))
 
Aliaksandr Hryshyn:
The hardest part will be drawing the buttons :))

Yeah, I figured that was the hardest part, because there aren't any. ))))

 

The scrolls were made separately, they can be applied to a specific window configuration, the rest (events, changes to required properties) will be done automatically. Connecting them is very simple:

   _scroll_v.Create(_main,_grid_cols,true,30);
   _scroll_h.Create(_main,_grid_cols,false,30);

Regardingthe difficulty of creating a table: the engine turned out very well, so creating a table using it is not that difficult.

//+------------------------------------------------------------------+
//|                                                       V_grid.mqh |
//|                                               Aliaksandr Hryshyn |
//|                          https://www.mql5.com/ru/users/greshnik1 |
//+------------------------------------------------------------------+
#property copyright "Aliaksandr Hryshyn"
#property link      "https://www.mql5.com/ru/users/greshnik1"

#include  <Greshnik\\\Windows_engine\\Windows_engine_base.mqh>
#include <Greshnik\\\Windows_engine\\V_objects\\V_scrollbar.mqh>

enum eG_property
  {
   gp_=0,
  };
//Таблица
class V_grid
  {
   int               _cols;//Количество столбцов
   int               _rows;//Количество строк
   int               _cell_width;//Ширина клетки
   int               _cell_height;//Высота клетки
   int               _scroll_width;//Ширина полосы прокрутки
   int               _size_caption;//Размер заголовков
   int               _size_fixing_col;//Размер фиксированного столбца
   bool              _is_captions;//Наличие заголовков
   bool              _is_cols_fixing;//Наличие первого фиксированного столбца
   bool              _is_scroll_bar_v;//Наличие вертикальной полосы прокрутки
   bool              _is_scroll_bar_h;//Наличие горизонтальной полосы прокрутки

   cV_object_base    *_main;//Основное окно
   cV_object_base    *_grid_view;//Окно отображения сетки
   V_scrollbar       _scroll_v;//Вертикалдьная прокрутка
   V_scrollbar       _scroll_h;//Горизонтальная прокрутка
   cV_object_base    *_caption_v;//Окно отображения заголовков
   cV_object_base    *_caption;//Окно с заголовками
   cV_object_base    *_col_fixing_v;//Окно отображения фиксированного столбца
   cV_object_base    *_col_fixing;//Фиксированный столбец
   cV_object_base    *_grid_cols;//Столбцы.Отсюда брать массивы столбцов

   //События, которые влияют на вертикальную прокрутку
   class Events_scroll_v_change: public iE_event_handler
     {
   public:
      V_grid         *_v_grid;
      void           On_event(sEvent &event);
     };
   Events_scroll_v_change scroll_v_change;

   //События, которые влияют на горизонтальную прокрутку
   class Events_scroll_h_change: public iE_event_handler
     {
   public:
      V_grid         *_v_grid;
      void           On_event(sEvent &event);
     };
   Events_scroll_h_change scroll_h_change;

   //События перемещения сетки
   class Events_grid: public iE_event_handler
     {
   public:
      V_grid         *_v_grid;
      void           On_event(sEvent &event);
     };
   Events_grid       events_grid;
public:
   //Создание таблицы
   bool              Create(
      cV_object_base &parent_object,
      string name=NULL
   );
   //Возвращает указатель на основной объект
   cV_object_base*   Get_main_v_object();

   //Изменение основных свойств таблицы
   void              Set_property(
      eG_property grid_property,
      long property_value
   );
   //Получение значения свойства
   long              Get_property(
      eG_property grid_property
   );//При ошибке возвращает LONG_MAX

   //Поучение объекта ячейки таблицы
   cV_object_base*   Get_cell_object(
      int pos_x,//Индекс столбца
      int pos_y//Индекс строки
   );//Возвращает объект ячейки или NULL при ошибке

   //Получение объекта столбца таблицы
   cV_object_base*   Get_col_object(
      int pos_x//Индекс столбца
   );//Возвращает объект ячейки или NULL при ошибке
  };

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
cV_object_base* V_grid::Get_col_object(int pos_x)
  {
   if((pos_x>=_grid_cols.Get_property(vop_s_childs_count).data_long)||(pos_x<0))
     {
      cLng_add_user(cV_object_base::lng_id,21,string(pos_x),"");
      return NULL;
     }
   return _grid_cols.Get_child(pos_x);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
cV_object_base* V_grid::Get_cell_object(int pos_x,int pos_y)
  {
   if((pos_x>=_grid_cols.Get_property(vop_s_childs_count).data_long)||(pos_x<0))
     {
      cLng_add_user(cV_object_base::lng_id,21,string(pos_x),"");
      return NULL;
     }
   cV_object_base *obj=_grid_cols.Get_child(pos_x);
   if((pos_y>=obj.Get_property(vop_s_childs_count).data_long)||(pos_y<0))
     {
      cLng_add_user(cV_object_base::lng_id,21,string(pos_x),"");
      return NULL;
     }
   return obj.Get_child(pos_y);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
long V_grid::Get_property(eG_property grid_property)
  {
   switch(grid_property)
     {
     }
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void V_grid::Set_property(eG_property grid_property,long property_value)
  {
   switch(grid_property)
     {
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void V_grid::Events_grid::On_event(sEvent &event)
  {
   switch(event.id)
     {
      case CHARTEVENT_ON_PROPERTY_CHANGED_:
        {
         switch(eV_object_property(event.lparam))
           {
            case vop_position_x:
              {
               _v_grid._caption.Set_property(vop_position_x,event.dparam);
               break;
              }
            case vop_position_y:
              {
               _v_grid._col_fixing.Set_property(vop_position_y,event.dparam);
               break;
              }
           }
         break;
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void V_grid::Events_scroll_v_change::On_event(sEvent &event)
  {

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void V_grid::Events_scroll_h_change::On_event(sEvent &event)
  {

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool V_grid::Create(cV_object_base &parent_object,string name=NULL)
  {
   if(CheckPointer(_main))
     {
      cLng_add_user(cV_object_base::lng_id,20,"V_grid","");
      return false;
     }
   scroll_v_change._v_grid=GetPointer(this);
   scroll_h_change._v_grid=GetPointer(this);
   events_grid._v_grid=GetPointer(this);
   _cols=5;
   _rows=5;
   _cell_width=400;
   _cell_height=400;
   _scroll_width=20;
   _size_caption=30;
   _size_fixing_col=30;
   _is_captions=true;
   _is_cols_fixing=true;
   _is_scroll_bar_v=true;
   _is_scroll_bar_h=true;

   int width=850;
   int height=850;

   _main=new cV_object_base();
   _main.Set_property_info(vop_position_x,20);
   _main.Set_property_info(vop_position_y,20);
   _main.Set_property_info(vop_size_x,width);
   _main.Set_property_info(vop_size_y,height);
   _main.Create(parent_object,name);

   _caption_v=new cV_object_base();
   if(_is_cols_fixing)
     {
      _caption_v.Set_property_info(vop_position_x,_size_fixing_col);
      if(_is_scroll_bar_v)
        {
         _caption_v.Set_property_info(vop_size_x,width-_scroll_width-_size_fixing_col);
        }
      else
        {
         _caption_v.Set_property_info(vop_size_x,width-_cell_width);
        }
     }
   else
     {
      _caption_v.Set_property_info(vop_position_x,0);
      if(_is_scroll_bar_v)
        {
         _caption_v.Set_property_info(vop_size_x,width-_scroll_width);
        }
      else
        {
         _caption_v.Set_property_info(vop_size_x,width);
        }
     }
   _caption_v.Set_property_info(vop_position_y,0);
   _caption_v.Set_property_info(vop_size_y,_size_caption);
   _caption_v.Set_property_info(vop_is_hidden,!_is_captions);
   _caption_v.Set_property_info(vop_is_anchor_left,true);
   _caption_v.Set_property_info(vop_is_anchor_right,true);
   _caption_v.Create(_main);
   _caption_v.Add_event_handler(GetPointer(scroll_v_change));
   _caption_v.Set_property_change_event(vop_is_hidden);

   _caption=new cV_object_base();
   _caption.Set_property_info(vop_position_x,0);
   _caption.Set_property_info(vop_position_y,0);
   _caption.Set_property_info(vop_size_x,_cols*_cell_width);
   _caption.Set_property_info(vop_size_y,_size_caption);
   _caption.Set_property_info(vop_is_canvas,true);
   _caption.Create(_caption_v);
   for(int i1=0; i1<_cols; i1++)
     {
      cV_object_base *col_caption=new cV_object_base();
      col_caption.Set_property_info(vop_position_x,i1*_cell_width);
      col_caption.Set_property_info(vop_position_y,0);
      col_caption.Set_property_info(vop_size_x,_cell_width);
      col_caption.Set_property_info(vop_size_y,_size_caption);
      col_caption.Set_property_info(vop_color_back,clrWhiteSmoke);
      col_caption.Set_property_info(vop_color_borders,clrGray);
      col_caption.Set_property_info(vop_border_type,long(BORDER_FLAT));
      col_caption.Set_property_info(vop_text_anchor,TA_CENTER|TA_VCENTER);
      col_caption.Set_property_info(vop_border_line_width,1);
      col_caption.Set_property_info(vop_text,"Col "+string(i1));
      col_caption.Set_property_info(vop_is_canvas_from_parent,true);
      col_caption.Create(_caption);
     }

   _col_fixing_v=new cV_object_base();
   _col_fixing_v.Set_property_info(vop_position_x,0);
   if(_is_captions)
     {
      _col_fixing_v.Set_property_info(vop_position_y,_size_caption);
      if(_is_scroll_bar_h)
        {
         _col_fixing_v.Set_property_info(vop_size_y,height-_size_caption-_scroll_width);
        }
      else
        {
         _col_fixing_v.Set_property_info(vop_size_y,height-_size_caption);
        }
     }
   else
     {
      _col_fixing_v.Set_property_info(vop_position_y,0);
      if(_is_scroll_bar_h)
        {
         _col_fixing_v.Set_property_info(vop_size_y,height-_scroll_width);
        }
      else
        {
         _col_fixing_v.Set_property_info(vop_size_y,height);
        }
     }
   _col_fixing_v.Set_property_info(vop_size_x,_size_fixing_col);
   _col_fixing_v.Set_property_info(vop_is_anchor_top,true);
   _col_fixing_v.Set_property_info(vop_is_anchor_bottom,true);
   _col_fixing_v.Set_property_info(vop_is_hidden,!_is_cols_fixing);
   _col_fixing_v.Create(_main);

   _col_fixing=new cV_object_base();
   _col_fixing.Set_property_info(vop_position_x,0);
   _col_fixing.Set_property_info(vop_position_y,0);
   _col_fixing.Set_property_info(vop_size_x,_size_fixing_col);
   _col_fixing.Set_property_info(vop_size_y,_rows*_cell_height);
   _col_fixing.Set_property_info(vop_is_canvas,true);
   _col_fixing.Create(_col_fixing_v);
   for(int i1=0; i1<_rows; i1++)
     {
      cV_object_base *cell_fixing=new cV_object_base();
      cell_fixing.Set_property_info(vop_position_x,0);
      cell_fixing.Set_property_info(vop_position_y,i1*_cell_height);
      cell_fixing.Set_property_info(vop_size_x,_size_fixing_col);
      cell_fixing.Set_property_info(vop_size_y,_cell_height);
      cell_fixing.Set_property_info(vop_color_back,clrWhiteSmoke);
      cell_fixing.Set_property_info(vop_color_borders,clrGray);
      cell_fixing.Set_property_info(vop_border_type,long(BORDER_FLAT));
      cell_fixing.Set_property_info(vop_text_anchor,TA_CENTER|TA_VCENTER);
      cell_fixing.Set_property_info(vop_border_line_width,1);
      cell_fixing.Set_property_info(vop_text,string(i1));
      cell_fixing.Set_property_info(vop_is_canvas_from_parent,true);
      cell_fixing.Create(_col_fixing);
     }

   _grid_view=new cV_object_base();
   if(_is_cols_fixing)
     {
      _grid_view.Set_property_info(vop_position_x,_size_fixing_col);
      if(_is_scroll_bar_v)
        {
         _grid_view.Set_property_info(vop_size_x,width-_size_fixing_col-_scroll_width);
        }
      else
        {
         _grid_view.Set_property_info(vop_size_x,width-_size_fixing_col);
        }
     }
   else
     {
      _grid_view.Set_property_info(vop_position_x,0);
      if(_is_scroll_bar_v)
        {
         _grid_view.Set_property_info(vop_size_x,width-_scroll_width);
        }
      else
        {
         _grid_view.Set_property_info(vop_size_x,width);
        }
     }
   if(_is_captions)
     {
      _grid_view.Set_property_info(vop_position_y,_size_caption);
      if(_is_scroll_bar_h)
        {
         _grid_view.Set_property_info(vop_size_y,height-_size_caption-_scroll_width);
        }
      else
        {
         _grid_view.Set_property_info(vop_size_y,height-_size_caption);
        }
     }
   else
     {
      _grid_view.Set_property_info(vop_position_y,0);
      if(_is_scroll_bar_h)
        {
         _grid_view.Set_property_info(vop_size_y,height-_scroll_width);
        }
      else
        {
         _grid_view.Set_property_info(vop_size_y,height);
        }
     }
   _grid_view.Set_property_info(vop_is_anchor_left,true);
   _grid_view.Set_property_info(vop_is_anchor_right,true);
   _grid_view.Set_property_info(vop_is_anchor_top,true);
   _grid_view.Set_property_info(vop_is_anchor_bottom,true);
   _grid_view.Create(_main);
   _grid_view.Add_event_handler(GetPointer(scroll_v_change));
   _grid_view.Set_property_change_event(vop_size_y);

   _grid_cols=new cV_object_base();
   _grid_cols.Set_property_info(vop_position_x,0);
   _grid_cols.Set_property_info(vop_position_y,0);
   _grid_cols.Set_property_info(vop_size_x,_cols*_cell_width);
   _grid_cols.Set_property_info(vop_size_y,_rows*_cell_height);
   _grid_cols.Create(_grid_view);
   _grid_cols.Add_event_handler(GetPointer(events_grid));
   _grid_cols.Set_property_change_event(vop_position_x);
   _grid_cols.Set_property_change_event(vop_position_y);

   _scroll_v.Create(_main,_grid_cols,true,30);
   _scroll_h.Create(_main,_grid_cols,false,30);

   for(int i1=0; i1<_cols; i1++)
     {
      cV_object_base *col=new cV_object_base();
      col.Set_property_info(vop_position_x,i1*_cell_width);
      col.Set_property_info(vop_position_y,0);
      col.Set_property_info(vop_size_x,_cell_width);
      col.Set_property_info(vop_size_y,_rows*_cell_height);
      col.Create(_grid_cols);
      for(int i2=0; i2<_rows; i2++)
        {
         cV_object_base *cell=new cV_object_base();
         cell.Set_property_info(vop_position_x,0);
         cell.Set_property_info(vop_position_y,i2*_cell_height);
         cell.Set_property_info(vop_size_x,_cell_width);
         cell.Set_property_info(vop_size_y,_cell_height);
         cell.Set_property_info(vop_color_back,clrSlateGray);
         cell.Set_property_info(vop_color_text,clrBlack);
         cell.Set_property_info(vop_text_anchor,TA_CENTER|TA_VCENTER);
         cell.Set_property_info(vop_text,string(i1*_rows+i2));
         cell.Set_property_info(vop_color_back_mouse_moving,clrDimGray);
         cell.Create(col);
        }
     }
   return true;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
cV_object_base* V_grid::Get_main_v_object()
  {
   return GetPointer(_main);
  }
//+------------------------------------------------------------------+
 
It would be nice if someone would get busy making a graphic library for creating controls
 
Реter Konow:

Yeah, I figured that's the hardest part, because there aren't any. ))))

A demo for your monitor. For the bottom right corner you can resize the table

Files:
Test_v_grid.ex5  502 kb
 
Aliaksandr Hryshyn:

A demo for your monitor. For the bottom right corner you can resize the table

Thanks for the demo for my monitor.

And so:

  • The "rubbery" windows mechanism is initially implemented,

but when resizing:

  1. windows should not blink,
  2. there should be 8 window grip handles for resizing - for each side and each corner.
  • In fact, the window as an entity is not formed. There is no integrity yet.

By idea, you should come to a similar option:

Well, on the whole, you certainly have done well! I didn't expect it. ))))

Carry on.
 

I remembered !

I remembered what it all reminds me of...

demos from GVision (one of TVision's descendants).

In about 93-95 you could buy the above-mentioned demos (*who doesn't know - the software was sold in retail) in the bookstore "House of Tech Books" on Leninsky Street.
Even had a separate monitor where the demo was scrolling, and you could "try". It was cool - the signs, the buttons, the check/radio boxes, and the graphics...

but then I bought a Zortec-C. A weighty box, with 5 volumes of documentation and some floppy disks :-)

nice to remember.

 
Реter Konow:

Thanks for the demo for my monitor.

And so:

  • The "rubbery" windows mechanism is initially implemented,

but when you resize:

  1. windows should not blink,
  2. there should be 8 window grip handles for resizing - for each side and each corner.
  • In fact, the window as an entity is not formed. There is no integrity yet.

By idea, you should come to a similar option:

Well, on the whole, you certainly did well! I didn't expect it. ))))

Continue.

1. used rectangles and kanvasses in large numbers with dynamics, maybe not blink if everything was on one kanvas, there are already limitations of the platform, and draw everything on one kanvas is not desirable. Maybe if only to translate all at once on DirectX...

2. I've just added one small component, which implements the stretch. And there's no integrity, it's just assembled elements, and not necessarily graphic.

What didn't you expect? Stretching? That's how easy it is for me. I make these things for my project, I don't have plans to create library of graphic controls, although the basis for its creation is very good

#include  <Greshnik\\\Windows_engine\\Windows_engine_base.mqh>

//Элемент, который будет изменять размер родительского окна перетаскиванием мышки
//По умолчанию окошко будеи распологаться в правом нижнем углу
class cV_resizer
  {
   cV_object_base    *_main;//Основное окно
   class My_events: public iE_event_handler
     {
   public:
      cV_object_base *_e_my;
      void           On_event(sEvent &event);
     };
   My_events         ev;
public:
   //Создание таблицы
   bool              Create(
      cV_object_base &parent_object,
      string name=NULL
   );
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void cV_resizer::My_events::On_event(sEvent &event)
  {
   if(event.id==CHARTEVENT_ON_PROPERTY_CHANGED_)
     {
      if(event.lparam==vop_position_x)
        {
         cV_object_base *par=_e_my.Get_parent();
         long p=par.Get_property(vop_size_x).data_long;
         long pos=_e_my.Get_property(vop_position_x).data_long;
         long size=_e_my.Get_property(vop_size_x).data_long;
         long d=pos+size-p;
         par.Set_property(vop_size_x,p+d);
         _e_my.Set_property(vop_position_x,par.Get_property(vop_size_x).data_long-size);
        }
      else
        {
         cV_object_base *par=_e_my.Get_parent();
         long p=par.Get_property(vop_size_y).data_long;
         long pos=_e_my.Get_property(vop_position_y).data_long;
         long size=_e_my.Get_property(vop_size_y).data_long;
         long d=pos+size-p;
         par.Set_property(vop_size_y,p+d);
         _e_my.Set_property(vop_position_y,par.Get_property(vop_size_y).data_long-size);
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool cV_resizer::Create(cV_object_base &parent_object,string name=NULL)
  {
   int width=20;
   int height=20;
   long width_p=parent_object.Get_property(vop_size_x).data_long;
   long heigth_p=parent_object.Get_property(vop_size_y).data_long;

   _main=new cV_object_base();
   _main.Set_property_info(vop_size_x,width);
   _main.Set_property_info(vop_size_y,height);

   _main.Set_property_info(vop_position_x,width_p-width);
   _main.Set_property_info(vop_position_y,heigth_p-height);
   _main.Set_property_info(vop_is_movable,true);
   _main.Create(parent_object);
   _main.Add_event_handler(GetPointer(ev));
   _main.Set_property_change_event(vop_position_x);
   _main.Set_property_change_event(vop_position_y);

   ev._e_my=GetPointer(_main);
   return true;
  }
 
Aliaksandr Hryshyn:

1. rectangles and kanvasses are used in large quantities with dynamics, maybe it wouldn't blink if everything was on one kanvas, but there are already platform limitations, and drawing everything on one kanvas is not desirable. Maybe if only to translate all at once on DirectX...

2. I've just added one small component, which implements the stretch. And there's no integrity, it's just assembled elements, and not necessarily graphic.

What didn't you expect? Stretching? That's how easy it is for me:

It blinks because you change size of the WHOLE kanvas, which is resource-consuming, but if you change area of visible image on kanvas of MAXIMUM size, you get rid of this unpleasant effect. That is, you create a kanvas of monitor's screen size in advance, connect the image to it (of the same size) and then "crop" it. And the resizing functions will only define the visible area of the canvas, not recreate it again.

Reason: