Создание графической библиотеки с нуля - страница 14

 
Попробуйте сделать полноценное окно. Как виндоус форма. Можно без динамичности, но раз уж Вы ее частично реализовали, думаю получится виндоус-подобное "резиновое" окно.  
 
Реter Konow:
Попробуйте сделать полноценное окно. Как виндоус форма. Можно без динамичности, но раз уж Вы ее частично реализовали, думаю получится виндоус-подобное "резиновое" окно.  
Самое сложное будет нарисовать кнопочки :))
 
Aliaksandr Hryshyn:
Самое сложное будет нарисовать кнопочки :))

Да, я так и понял, что это самое сложное, потому что их нет.)))) 

 

Прокрутки делались отдельно, их можно применять к определённой конфигурации окон, остальное(события,изменения необходимых свойств) будет сделано автоматически. Подключение их очень простое:

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

По поводу сложности создания таблицы: движок очень хороший получился, поэтому создание таблицы, используя его, не так уж сложно. 

//+------------------------------------------------------------------+
//|                                                       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);
  }
//+------------------------------------------------------------------+
 
Хорошо бы, чтобы кто-нибудь занялся делать графическую библиотеку для создания элементов управление
 
Реter Konow:

Да, я так и понял, что это самое сложное, потому что их нет.)))) 

Демка для вашего монитора. За правый нижний угол можно изменять размер таблицы

Файлы:
Test_v_grid.ex5  502 kb
 
Aliaksandr Hryshyn:

Демка для вашего монитора. За правый нижний угол можно изменять размер таблицы

Спс за демку для моего монитора.

И так:

  • Механизм "резиновости" окон начально реализован, 

       но при изменении размеров:

  1. моргать окна не должны, 
  2. ручек ухвата окон для изменения размеров должно быть 8 - за каждую сторону и каждый угол.
  • Фактически, окно как сущность не сформировано. Пока еще нет целостности.

По идеи, Вы должны прийти к подобному варианту:

Ну а в целом, Вы конечно, молодец! Не ожидал.))))

Продолжайте.
 

вспомнил !

я вспомнил что всё это мне напоминает...

демки от GVision (один из потомков TVision).

Году эдак около 93-95 упомянутое можно было купить (*кто не в курсе - софт продавался в розницу) в книжном магазине "Дом Тех.Книги" на Ленинском.
Даже стоял отдельный монитор где демка прокручивалась,и можно было "попробовать". Это было круто - таблички, кнопочки, чек/радио-боксы, и в графике..

но я тогда купил Zortec-C. Увесистая коробка, с 5 томами документации и сколько-то дискеток :-) 

приятно вспомнить.

 
Реter Konow:

Спс за демку для моего монитора.

И так:

  • Механизм "резиновости" окон начально реализован, 

       но при изменении размеров:

  1. моргать окна не должны, 
  2. ручек ухвата окон для изменения размеров должно быть 8 - за каждую сторону и каждый угол.
  • Фактически, окно как сущность не сформировано. Пока еще нет целостности.

По идеи, Вы должны прийти к подобному варианту:

Ну а в целом, Вы конечно, молодец! Не ожидал.))))

Продолжайте.

1. Используются прямоугольники и канвасы в большом количестве с динамикой, может и не моргало если бы всё было на одном канвасе, тут уже ограничения платформы, а рисовать всё на одном канвасе нету желания. Может только если сразу всё на DirectX перевести...

2. Просто добавил один небольшой компонент, который реализует растягивание, на таблице тестировал. А целостности и нету, это просто сборные элементы, и не обязательно графические

Что не ожидали? Растягивание? Так это легко всё делается у меня. Я делаю эти штуки для своего проекта, создавать библиотеку графических элементов управления у меня нету в планах, хотя основа для её создания очень хорошая

#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. Используются прямоугольники и канвасы в большом количестве с динамикой, может и не моргало если бы всё было на одном канвасе, тут уже ограничения платформы, а рисовать всё на одном канвасе нету желания. Может только если сразу всё на DirectX перевести...

2. Просто добавил один небольшой компонент, который реализует растягивание, на таблице тестировал. А целостности и нету, это просто сборные элементы, и не обязательно графические

Что не ожидали? Растягивание? Так это легко всё делается у меня:

Моргает, потому что меняете размер ВСЕГО канваса, что ресурсо-затратно, однако, если менять область вимимого изображения на канвасе МАКСИМАЛЬНОГО размера, избавитесь от этого неприятного эффекта. Т.е. заранее создаете канвас размером с экран монитора, подключаете к нему изображение (такого же размера), а затем "обрезаете" его. А функции изменения размеров определяют только область видимости канваса, не пересоздавая его заново.