Делаем краудсорсовый проект по Canvas - страница 23

 
Реter Konow:

))) Ну так а для чего я эту тему завел? ) Буду сейчас ООП изучать. 


В этом и преимущество твоего пути - от практики к теории. Я тоже проделал этот путь. Моё нутро долго не принимало парадигму ООП, т.к. я еще начинал программировать, когда его в природе не существовало. Но сейчас я понимаю, что это самое ценное изобретение в программировании. И порой мне кажется, что если бы ООП до сих пор никто не придумал, то я придумал бы его сам :))
Тебе, Петр понравиться и ты будешь в восторге, когда осознаешь всю прелесть ООП и какие возможности оно открывает. Я тебя уверяю :)). И ничего сложного и запутанного в ООП нет, особенно для тебя с твоим опытом программирования. И мне кажется, в твоем случае может даже хватить документации Метаквотов, чтобы въехать в суть. Литературы море.
Реter Konow:

Но Николай, я так и не понял того, о чем спрашивал, - есть ли в классе CCcanvas  возможность задавать конкретный цвет линиям градиента рамки? Смотря на твой пример, можно подумать что есть... Если так, то можешь ли ты нарисовать что то похожее на мой пример?

Ладно, ОК. Хоть это и не тема этой ветки, но попробую чуть прояснить вещи, кажущимися очевидными для знающий программистов, но не очевидными для программистов, столкнувшимися с Канвасом впервые.
Итак, что такое Canvas. В переводе с английского - холст. Это просто любая область экрана в пределах окна, к которому он потом прикрепляется. Главные его характеристики это его размер: Ширина(Width) и Высота(Height). И по сути это одномерный массив точек типа uint (4 байта) размерностью Width*Height. В реализации класса CCanvas этот массив называется m_pixels, по умолчанию он privat (что означает доступность только в внутри класса), но я лично всегда делаю его public (доступен не только внутри класса, но и в пользовательских приложениях), т.к хочу оперировать с массивом данных непосредственно. Каждая точка этого холста может принимать любое значение типа color (тоже 4 байта как и uint, один байт резервный), что означает точку любого цвета RGB. Каждому цвету (Red, Green или Blue) соответствует один байт (256 значений), и соответственно всего цветов RGB существует  256*256*256=16 777 216.

Чтобы поставить точку  скажем красного цвета в координатах X,Y, где X может принимать значения от 0 до (Width-1), а Y от 0 до (Height-1)  просто достаточно присвоить значение красного цвета ячейки массива m_pixels с номером (Y*Width+X) :

m_pixels[Y*Width+X]=clrRed;

или что тоже самое:

m_pixels[Y*Width+X] = 0x0000FF; // 0x00FF00 зеленый, - 0xFF0000 - синий, 0x00FFFF - желтый и т.д.

Это ВСЁ!!!
Вы теперь можете даже не пользоваться встроенными функциями класса CCanvas(что конечно же глупо, т.к. там есть много чего полезного) . Если вы можете поставить точку на экране в любом месте и любого цвета - вы Бог, что хотите, то и рисуйте: кнопки, графики, создавайте свой собственный GDI и т.д. и т.п.

И если кто-то думает что канвас работает медленно, то он ошибается. Канвас невероятно шустрый и это заслуга команды разработчиков. Я тестировал неоднократно скорость рисования канваса и с использованием Dll библиотек, написанных на С++. Сейчас после обновлений последнего года канвас на МТ5 работает почти так же быстро, как если бы вы его писали в Visual Studio на С++. Всего лишь на 10-15 % медленее. И не забывайте - Windows написана на С++ и это сплошной Canvas. В этом и есть прелесть и перспективы MT5  с его MQL5!!! Такой скоростью не сможет похвастаться ни Java, ни C#, как писали некоторые в этой ветке.

Не даром разработчики недавно ввели новое свойство CHART_SHOW для отключения отображения графика.
Продемонстрирую это примером скрипта:

//+------------------------------------------------------------------+
//|                                                  CleanScreen.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+

// Внимание !!! В классе CCanvas массив m_pixels должен быть определен как public
#include <Canvas\Canvas.mqh>

void OnStart()
  {
   ChartSetInteger(0,CHART_SHOW,false); // очищаем экран от всего
   int Width =(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);  // получаем Ширину экрана
   int Height=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); // получаем Высоту экрана

   CCanvas C;   // создаем объект Canvas
   if(!C.CreateBitmapLabel(0,0,"CleanScreen",0,0,Width,Height,COLOR_FORMAT_XRGB_NOALPHA)) // Создаем холст на весь экран
      Print("Error creating canvas: ",GetLastError());

// Теперь что-нибудь нарисуем на этом чистом экране
// например красную точку в центре экрана
   int X=Width/2;
   int Y=Height/2;
   C.m_pixels[Y*Width+X]=0xFF0000; // красный
                                   // или нарисуем окружность в центре с радиусом 100 по точкам фиолетового цвета
   int r=100;
   int q=(int)ceil(r*M_SQRT1_2);
   int r2=r*r;
   for(int x=0; x<=q; x++)
     {
      int y=(int)round(sqrt(r2-x*x));
      C.m_pixels[(Y+y)*Width+X+x]=0xFF00FF;
      C.m_pixels[(Y+y)*Width+X-x]=0xFF00FF;
      C.m_pixels[(Y-y)*Width+X+x]=0xFF00FF;
      C.m_pixels[(Y-y)*Width+X-x]=0xFF00FF;
      C.m_pixels[(Y+x)*Width+X+y]=0xFF00FF;
      C.m_pixels[(Y+x)*Width+X-y]=0xFF00FF;
      C.m_pixels[(Y-x)*Width+X+y]=0xFF00FF;
      C.m_pixels[(Y-x)*Width+X-y]=0xFF00FF;
     }
// конечно же можно окружность построить проще :) - через встроенную функцию класса CCanvas:
   C.Circle(X,Y,r+20,0xFFFF00); // желтого цвета
   C.Update(); // Теперь выводим это на экран
  }

Работа данного скрипта:


Экран очищается, но доступ к котировкам остается и мы можем с помощью этого чистого холста сделать свой интерфейс графика, например такой с градиентом:


Реter Konow:

 Но Николай, я так и не понял того, о чем спрашивал, - есть ли в классе CCcanvas  возможность задавать конкретный цвет линиям градиента рамки? Смотря на твой пример, можно подумать что есть... Если так, то можешь ли ты нарисовать что то похожее на мой пример? 

Цвет задается внутри класса GButton и там даже есть две функции для смешивания двух цветов и создания массива цветов перетекания от одного цвета к другому, т.е. как раз для градиента. Нужно только определиться с понятием градиента. В моем понимании градиент (или градиентная заливка) это плавное перетекание одного цвета в другой. В твоем примере нет градиентов, есть только 4 цвета. В моем примере внутри класса GButton из одного цвета формируются еще 4 дополнительных цветов различной яркости данного цвета, а также формируется массив цветов для градиентной заливки. Это как раз делается для того, чтобы упростить жизнь для конечного потребителя класса. Зачем ему заморачиваться с формированием этих цветов?
Нарисовать что то похожее на твой пример - это твое домашнее задание, Петр :)) Давай начинай разбираться в классах, а значит в ООП.
Удачи!
 
Nikolai Semko:

Удачи!

Ок, Николай. Спасибо и тебе тоже удачи!
 
Nikolai Semko:

Николай, я хотел ответить тебе вчера на твой содержательный пост, но не смог собраться с мыслями. Сейчас собрался, и понял, что писать нужно от сердца, а не от ума, иначе ничего не объясню. Конечно, получиться оффтоп и модераторы наверное удалят, но все же..

То, что ты пишешь об ООП вдохновляет. Я уже брался за его изучение с серьезным намерением его освоить. Однако, в процессе изучения меня постоянно одолевали вопросы из категории: "а зачем идти долгой дорогой, когда есть короткий путь?" Я постоянно видел легкие,  сжатые и четкие способы решения задач, а мне как будто говорили, - "Нет! В ООП так не решается. Нужно делать все по форме, чинно и благородно.". Я в ответ спрашивал себя,- "но как же так? Я же не нуждаюсь в этих сущностях. Зачем мне добавлять их в код? Они же лишние. Я хочу сжать код." А мне в ответ, - "Нет! это не профессионально. Это плохой код.".

Я очень много спорил сам с собой на тему ООП пытаясь понять, в чем же его преимущества для меня. Я думал, - "если я решаю задачи прекрасно и легко без ООП, почему же я должен его использовать? Зачем мне дополнительно усложнять простые и понятные мне вещи? Как, куда и зачем мне всовывать в свой код то, в чем я не нуждаюсь?". Потом я решил, что ООП мне не нужен потому, что я все делаю сам и получается у меня очень хорошо. Когда ты все делаешь сам и не расчитываешь что либо подключать и к тому же ищещь и находишь максимально эффективные решения, то возникает закономерный вопрос, - "а зачем что то еще?". Казалось бы, ООП дает удобства и порядок программе. Да, это так. Но у меня есть мой собственный порядок. Своя структура. Свои сущности. Свои правила. Почему же я должен от этого отказываться?

Как и наш организм отторгает чужую ткань, так и я не мог "срастись" с продуктом чужой мысли. Везде и во всем я чуствовал отторжение. ООП был для меня порядком, созданным чужой мыслью и он не проходил моего теста на эффективность. Именно этот тест и явился для меня решающим фактором. Я понял, что если буду пользоваться ООП я буду более слабым программистом, чем если пойду по своему пути и все задачи буду решать сам. Моя "программная сила" в том, что я пишу на понятном мне русском языке, использую общую глобальную память для графических объектов, которую называю "ядром", и создаю большие и сложные механизмы которые с этим ядром работают. В этом и заключается мой подход.

Я не буду программировать ООП до тех пор, пока кто то не победит меня с помощью этого подхода. Пока с его помощью не сделают то, что делаю я, но еще более эффективно. 

Я спрашивал про канвас, потому что хотел понять, почему по факту мой механизм оказывается более эффективным. Не в теориях, не в красоте кода, а на деле.

В любом случае, спасибо тебе Николай за вдохноляющую и направляющую поддержку. ))

 
Реter Konow:

...

Я не буду программировать ООП до тех пор, пока кто то не победит меня с помощью этого подхода. 

...


Этот кто-то, наверное, одна из тех ветряных мельниц, с которыми Вы так неистово сражаетесь в своём воображении. )
 
Anatoli Kazharski:

Этот кто-то, наверное, одна из тех ветряных мельниц, с которыми Вы так неистово сражаетесь в своём воображении. )
Ну вот! Троли набежали...))
 
Реter Konow:
Ну вот! Троли набежали...))
Успокойтесь Пётр. Это всего лишь мельницы. Они просто стоят, выполняют определённую функцию и не пытаются Вас победить. Хотя, кто знает, как это визуализируется в Вашем богатом воображении. Судя по всему, выглядит это очень эффектно. )
 
Реter Konow:

Я абсолютно не фанат ООП, но четко знать и уметь использовать его вы просто обязаны если считаете себя программистом, хотя бы ради самообразования.

А вот использовать его или нет для решения своих прикладных задач -- дело абсолютно ваше.

 
Anatoli Kazharski:
Успокойтесь Пётр. Это всего лишь мельницы. Они просто стоят, выполняют определённую функцию и не пытаются Вас победить. Хотя, кто знает, как это визуализируется в Вашем богатом воображении. Судя по всему, выглядит это очень эффектно. )

Анатолий, мельницы или нет, - мне нравится бороться и побеждать. Особенно в том, в чем я хорош. Нравится живая конкуренция, поединки и прочее... Это все часть эволюции и естественного отбора. Так что нормально... Главное, чтобы правила были честные.

Сотрудничать с единомышленниками, участвовать в общих проектах, работать в комманде тоже классно. А воображение, конечно, не должно подменять реальность. Если Вы это имели ввиду, то я согласен.

 
Комбинатор:

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

А вот использовать его или нет для решения своих прикладных задач -- дело абсолютно ваше.

В этом нельзя не согласиться.
 
Реter Konow:

Я не буду программировать ООП до тех пор, пока кто то не победит меня с помощью этого подхода. Пока с его помощью не сделают то, что делаю я, но еще более эффективно. 

Я спрашивал про канвас, потому что хотел понять, почему по факту мой механизм оказывается более эффективным. Не в теориях, не в красоте кода, а на деле.

В любом случае, спасибо тебе Николай за вдохноляющую и направляющую поддержку. ))

Если соревнуются два программиста с одинаковым опытом и интелектом, создавая аналогичные большые проекты. Но первый использует только функции, а второй функции и классы. Однозначно победа будет за вторым. Но, повторюсь - если это объемный проект, просто он его сделает быстрее, т.к. багов будет меньше и порядка больше. И продукт у второго получится более читаемым, ремонтопригодным и более легко обновляемым и пополняемым. Это даже не мое имхо, это просто констатация факта. Лопатой вырыть яму легче, чем совочком. Если бы ты свой механизм реализовал не только на функциях, но и классах, он бы стал более эффективным. Вот это уже моё имхо.

И, Петр, я тут посмотрел бегло твой код, и понял что ты вовсю используешь канвас( правда не класс CCanvas, но какая разница). Тогда к чему эти все вопросы про канвас и зачем я тут распинался? :)). 

Причина обращения: