Обсуждение статьи "Графические интерфейсы I: Подготовка структуры библиотеки (Глава 1)" - страница 3

 
AlexBar3073:

...Но с точки зрения ООП предложенный метод имеет наибольшие шансы практической реализации. :) 

Легче сказать, чем сделать.

AlexBar3073:

...

Рассмотрим к примеру функции по перемещению формы по графику.

В функции нужно выполнять перечисление всех созданных объектов формы. Для чего? Ведь все созданные элементы помещаются в контейнер (массив)  самой формы. Для чего в функции перечислять все создаваемые элементы? Почему нельзя просто обойти контейнер в цикле и выполнить изменение координат всех элементов?

...

Обратите внимание на то, какого типа (CChartObject) массив (m_objects), в который сохраняются указатели всех графических объектов того или иного элемента (CElement). Можно попробовать в этом случае использовать динамическое преобразование типов, но код тогда станет ещё сложнее и прожорливее по потреблению ресурсов, так как нужно будет делать дополнительные проверки на тип указателя.

Что касается метода Delete() и подобных, то там можно в цикле пройтись (просто руки пока не дошли), так как у всех объектов тип CChartObject.

Осторожно предположу, что всё станет намного проще после перехода ко второму этапу развития библиотеки, когда все элементы будут рисоваться. То есть будет один элемент - один объект (bmp).

 
Anatoli Kazharski:

дополнительные проверки на тип указателя. 

А как сделать проверку на тип указателя в MQL?

По моим данным никаких средств для этого у языка нет. Хотелось бы конечно проверку является ли объект инстансом конкретного класса или является ли он потомком класса в иерархии.

К примеру, я реализую MVC паттерн и для определенных моделей с редактируемыми свойствами (имеющих общего предка) я подписываю один view-объект. Для того, чтобы отобразить табличку свойств этого объекта. После изменений модели, идет перерисовка слушателя (view) с передачей объекта модели. 

Тут приходится приводить модель к одному из типов иерархии моделей (который умеет вернуть свойства). Но проверить, что пришел объект нужного типа нельзя.

Теоретически, сторонний программист создавая приложение для интерфейса, может допустить ошибку и подписать эту view на другую модель (из другой иерархии, не имеющую предка с редактируемыми свойствами) . В режиме исполнения это никак обработать нельзя и приложение вылетит.

 

Anatoli Kazharski:

Осторожно предположу, что всё станет намного проще после перехода ко второму этапу развития библиотеки, когда все элементы будут рисоваться. То есть будет один элемент - один объект (bmp).

Я как раз пошел по этому пути пару лет назад. Сначала я сделал DOM модель для интерфейса, рисование примитивов, агрегация видов, передачей событий (всплытие, остановка). Все рисовалось на граф объектах MQL и в принципе работало. Но когда количество объектов переваливало за 200, начинались довольно ощутимые тормоза вследствии накладных расходов при перерисовке каждого объекта. Поэтому все было заброшено еще на год, пока не появился Canvas. Тогда все удалось быстро перевести на нее заменив базовые методы draw у view и логику обновления, практически ничего больше не меняя. И теперь даже несколько тысяч view на экране не приводят к задержке отрисовки, т.к. в памяти рисуется и сравнивается все очень быстро, а на выходе только картинка, т.е. из объектов на чарте только 1 элемент. 

Правда за последний год, за неимением свободного времени, разработка библиотеки UI практически остановилась.


 

Чтобы не быть голословным, приведу пример интерфейса построенного на базе UI на одном элементе Canvas

 

 

 
Igor Volodin:

Чтобы не быть голословным приведу пример интерфейса построенного на базе UI на одном элементе Canvas

+ лайк )
 
Igor Volodin:

А как сделать проверку на тип указателя в MQL?

По моим данным никаких средств для этого у языка нет. Хотелось бы конечно проверку является ли объект инстансом конкретного класса или является ли он потомком класса в иерархии.

К примеру, я реализую MVC паттерн и для определенных моделей с редактируемыми свойствами (имеющих общего предка) я подписываю один view-объект. Для того, чтобы отобразить табличку свойств этого объекта. После изменений модели, идет перерисовка слушателя (view) с передачей объекта модели. 

Тут приходится приводить модель к одному из типов иерархии моделей (который умеет вернуть свойства). Но проверить, что пришел объект нужного типа нельзя.

Теоретически, сторонний программист создавая приложение для интерфейса, может допустить ошибку и подписать эту view на другую модель (из другой иерархии, не имеющую предка с редактируемыми свойствами) . В режиме исполнения это никак обработать нельзя и приложение вылетит.

...

Может быть через dynamic_cast ? Когда начинал разрабатывать библиотеку, dynamic_cast ещё не было. 

Что-то вроде этого (пример отсюда) :

class CFoo { };
class CBar { };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   void *vptr[2];
   vptr[0]=new CFoo();
   vptr[1]=new CBar();
//---
   for(int i=0;i<ArraySize(vptr);i++)
     {
      if(dynamic_cast<CFoo *>(vptr[i])!=NULL)
         Print("CFoo * object at index ",i);
      if(dynamic_cast<CBar *>(vptr[i])!=NULL)
         Print("CBar * object at index ",i);
     }
   CFoo *fptr=vptr[1];  // выдаст ошибку приведения указателей, vptr[1] не является объектом CFoo
  }
//+------------------------------------------------------------------+

//---

Igor Volodin:

Я как раз пошел по этому пути пару лет назад. Сначала я сделал DOM модель для интерфейса, рисование примитивов, агрегация видов, передачей событий (всплытие, остановка). Все рисовалось на граф объектах MQL и в принципе работало. Но когда количество объектов переваливало за 200, начинались довольно ощутимые тормоза вследствии накладных расходов при перерисовке каждого объекта. Поэтому все было заброшено еще на год, пока не появился Canvas. Тогда все удалось быстро перевести на нее заменив базовые методы draw у view и логику обновления, практически ничего больше не меняя. И теперь даже несколько тысяч view на экране не приводят к задержке отрисовки, т.к. в памяти рисуется и сравнивается все очень быстро, а на выходе только картинка, т.е. из объектов на чарте только 1 элемент. 

Правда за последний год, за неимением свободного времени, разработка библиотеки UI практически остановилась.

Это очень интересно. Поля ввода тоже свои реализовали ? 

 
Igor Volodin:

Чтобы не быть голословным, приведу пример интерфейса построенного на базе UI на одном элементе Bitmap

Выглядит круто. Спасибо за пример. )

Здесь тема была, где Ваши рекомендации были бы весьма кстати: Делаем краудсорсовый проект по Canvas 

 
Anatoli Kazharski:

Может быть через dynamic_cast ? Когда начинал разрабатывать библиотеку dynamic_cast ещё не было. 

CFoo *foo = dynamic_cast<CFoo *>(&bar); // критической ошибки выполнения не возникнет


О, не видел. Спасибо. Оказывается в августе добавили. Вернет NULL и критической ошибки не возникнет - уже очень хорошо. Можно работать )

 

Anatoli Kazharski:

Поля ввода тоже свои реализовали ? 

 С полями ввода сделано так:

при событии focus на объекте редактируемого поля в UI вставляется графический объект редактируемого поля нужной конфигурации с текущим значением, с которым можно работать, используя в том числе буфер ввода (без него в интерфейсе никак),

при событии blur значение поля сохраняется (а системный граф объект -  Edit удаляется). А значение выводится уже на bmp текстом.

 

Igor Volodin:

... 

С полями ввода сделано так:

при событии focus на объекте редактируемого поля в UI вставляется графический объект редактируемого поля нужной конфигурации с текущим значением, с которым можно работать, используя в том числе буфер ввода (без него в интерфейсе никак),

при событии blur значение поля сохраняется (а системный граф объект -  Edit удаляется). А значение выводится уже на bmp текстом.

Ага, понял. Спасибо за уточнение.

Думаю, что это самый оптимальный вариант, но хочется в итоге попробовать реализовать всё таким образом, чтобы вообще всё рисовалось на одном объекте. Это позволило бы получить полную независимость и опыт, когда неважно в какой среде создаёшь графический интерфейс. Допустим, есть только холст и больше ничего. )

 
Anatoli Kazharski:

Выглядит круто. Спасибо за пример. )

Здесь тема была, где Ваши рекомендации были бы весьма кстати: Делаем краудсорсовый проект по Canvas 

Спасибо. Смотря на ваш объем работ по интерфейсу, вам большой респект. Я бы так не смог. Во первых - публичность, во-вторых последовательность. 

Краудсорсовый? Рискованно. Конечно при наличии стабильного дохода и свободного времени, возможно и потрудиться на благо общества. Но MQL общество будет использовать ее для коммерческих продуктов, а не для бесплатных. И одной GPL лицензией это не запретишь.

Т.е. если коротко, не вижу профита для себя.

 
Anatoli Kazharski:

но хочется в итоге попробовать реализовать всё таким образом, чтобы вообще всё рисовалось на одном объекте. Это позволило бы получить полную независимость и опыт, когда неважно в какой среде создаёшь графический интерфейс. Допустим, есть только холст и больше ничего. )

Просите у Рената функции работы с системным буфером и можно все нарисовать.
Причина обращения: