Canvas - это круто! - страница 44

 
Nikolai Semko:

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

Во всяком случае точно нужно штатную функцию PixelTransform заменить на эту:

https://www.mql5.com/ru/forum/1111/page2553#comment_13054823

Свою double (где все int входные параметры double) версию начал писать, но не дописал, отложил на полку. Не очень простая задача на кажущуюся простоту. Точнее написать не проблема, проблема написать очень качественно, чтобы быстрый алгоритм был. Моя главная проблема - это Перфекционизм.

Понятно, не допилили)

Я вряд ли сподвигнусь на переписывание всего канваса. Придется пока рисовать 2 однопиксельные рядом вместо 1 двухпиксельной )

 
Andrey Khatimlianskii:

Понятно, не допилили)

Я вряд ли сподвигнусь на переписывание всего канваса. Придется пока рисовать 2 однопиксельные рядом вместо 1 двухпиксельной )

На самом деле не нужно переписывать весь канвас. Главное сделать окружнсть формата 

Circle(double x, double y, double r1, double r2=0, uint clr)  

и линии нормальные сделать

Polyline(const double &x[],const double &y[], const uint clr,const double size,const uint style,ENUM_LINE_END end_style)

это покроет выполнение 95% задач

 

Forum on trading, automated trading systems and testing trading strategies

how to convert all objects into 1 object

Nikolai Semko, 2019.10.05 22:39

Indeed, Canvas is the solution.

And Canvas is much easier than it seems at first glance.

Here is a primitive example of an indicator (MQL5 & MQL4) with one object OBJ_BITMAP_LABEL in which there are many windows.

#property indicator_chart_window
#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164 - MQL5
                              //https://www.mql5.com/en/code/23840 - MQL4

struct win {
   int               x;
   int               y;
   int               width;
   int               height;
   uint              clr;
};
win wnd[30];
int OnInit() {
   for (int i=0; i<ArraySize(wnd); i++) {
      wnd[i].width=rand()%200+70;
      wnd[i].height=rand()%150+50;
      wnd[i].x=rand()%(W.Width-wnd[i].width);
      wnd[i].y=rand()%(W.Height-wnd[i].height);
      wnd[i].clr=ARGB(255,rand()%150+100,rand()%150+100,rand()%150+100);
   }
   ShowAllWind();
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+

int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) {
   return(rates_total);
}

//+------------------------------------------------------------------+

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam) {
   static bool click = false;
   static int x_mouse=0, y_mouse=0;
   static int focus=-1, xfocus=0, yfocus=0;
   int x=(int)lparam;
   int y=(int)dparam;
   if (sparam!="1" && click) focus=-1;
   if (sparam=="1" && !click) {
      focus=-1;
      for (int i=ArraySize(wnd)-1; i>=0; i--) {
         if (wnd[i].x<x && wnd[i].y<y && wnd[i].x+wnd[i].width>x && wnd[i].y+20>y) {
            focus=i;
            xfocus=x;
            yfocus=y;
            break;
         }
      }
      if (focus>=0) ChartSetInteger(0,CHART_MOUSE_SCROLL,false);
      else ChartSetInteger(0,CHART_MOUSE_SCROLL,true);
   }
   click=(sparam=="1")?true:false;
   if (id==CHARTEVENT_MOUSE_MOVE && focus>=0) {
      wnd[focus].x+=x-xfocus;
      wnd[focus].y+=y-yfocus;
      xfocus=x;
      yfocus=y;
      ShowAllWind();
   }
   if (id==CHARTEVENT_CHART_CHANGE) ShowAllWind();
}

//+------------------------------------------------------------------+

void ShowAllWind() {
   Canvas.Erase();
   for (int i=0; i<ArraySize(wnd); i++) {
      Canvas.FillRectangle(wnd[i].x,wnd[i].y,wnd[i].x+wnd[i].width,wnd[i].y+wnd[i].height,ARGB(255,GETRGBR(wnd[i].clr)*0.5,GETRGBG(wnd[i].clr)*0.5,GETRGBB(wnd[i].clr)*0.5));
      Canvas.FillRectangle(wnd[i].x+3,wnd[i].y+23,wnd[i].x+wnd[i].width-3,wnd[i].y+wnd[i].height-3,wnd[i].clr);
      Canvas.FillRectangle(wnd[i].x+3,wnd[i].y+3,wnd[i].x+wnd[i].width-3,wnd[i].y+20,ARGB(255,GETRGBR(wnd[i].clr)*0.7,GETRGBG(wnd[i].clr)*0.7,GETRGBB(wnd[i].clr)*0.7));
   }
   Canvas.Update();
}
//+------------------------------------------------------------------+

 
Nikolai Semko:

Класс!

Мне очень нужна такая возможность, и чтобы в этих миниокошках можно было рисовать свои индикаторы.

Почему одно окно скрывается под другим, а другое ложится сверху, можно исправить?

Еще вопросы, если такой же индикатор запустить на другом чарте, будет работать? Не будут события перекликаться как в стандартной библиотеке?

И если оба окна с одинаковыми координатами, какое окно будет перетаскиваться мышкой?

Можно ли с помощью мышки менять размер окна?

 
Sergey Chalyshev:

Класс!

Мне очень нужна такая возможность, и чтобы в этих миниокошках можно было рисовать свои индикаторы.

Почему одно окно скрывается под другим, а другое ложится сверху, можно исправить?

Еще вопросы, если такой же индикатор запустить на другом чарте, будет работать? Не будут события перекликаться как в стандартной библиотеке?

И если оба окна с одинаковыми координатами, какое окно будет перетаскиваться мышкой?

Можно ли с помощью мышки менять размер окна?

В данном примере просто реализово старшинство окон. По сути чем меньше индекс в массиве структур win, тем ниже виртуальный слой окна. 

Можно реализовать как угодно. Например если "схватили" окно, то оно стало самым верхним на экране и в массиве.

Можно реализовать прозрачность. Здесь показывал как это сделать. (там нужно обрабатывать кажный пискель).

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

с канвасом можно все в пределах своего окна и других окон МТ. 
Более того, можно откреплять окно от МТ5 и отправлять его в свободное плавание, хоть между мониторами. Здесь это можно увидеть.

 
Nikolai Semko:

В данном примере просто реализово старшинство окон. По сути чем меньше индекс в массиве структур win, тем ниже виртуальный слой окна. 

Можно реализовать как угодно. Например если "схватили" окно, то оно стало самым верхним на экране и в массиве.

Можно реализовать прозрачность. Здесь показывал как это сделать. (там нужно обрабатывать кажный пискель).

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

с канвасом можно все в пределах своего окна и других окон МТ. 
Более того, можно откреплять окно от МТ5 и отправлять его в свободное плавание, хоть между мониторами. Здесь это можно увидеть.

Немного не то, наверно не правильно задал вопрос.

В одной программе (скрипте, индикаторе) не сложно организовать несколько окон.

Я хочу сделать индикатор, который будет показывать данные в своём небольшом окне на чарте. И чтобы это окно можно было располагать удобно на чарте, перетаскивать мышкой, менять размер окна мышкой (желательно но можно и без этого). Надо запускать несколько таких индикаторов на чарте, каждый со своими параметрами. Пока не могу сообразить как сделать, чтобы события разных индикаторов не пересекались и индикатор адекватно реагировал на события мыши. И пока не решил что лучше, проще, канвас или объекты. С стандартной библиотекой Dialog ничего не получается.

 
Sergey Chalyshev:

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

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

 
Dmitry Fedoseev:

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

Естественно, так и делаю. Проблема в перетаскивании мышью. Если у объектов одинаковые координаты, один находится точ-в-точ под другим. При клике мышкой на них, какой отреагирует?

Про какие клубы вы говорите, я ни в какие клубы не записывался и не собираюсь ))

p.s. можете показать пример?

 
Sergey Chalyshev:

Естественно, так и делаю. Проблема в перетаскивании мышью. Если у объектов одинаковые координаты, один находится точ-в-точ под другим. При клике мышкой на них, какой отреагирует?

Про какие клубы вы говорите, я ни в какие клубы не записывался и не собираюсь ))

p.s. можете показать пример?

Про клуб не туда написал, извините... надо завязывать с этим клубом))

Какой-то один объект отреагирует. Наверно над при активации объекта менять ему Z-order, что бы он был выше всех. Надо попробовать.

 
Sergey Chalyshev:

Естественно, так и делаю. Проблема в перетаскивании мышью. Если у объектов одинаковые координаты, один находится точ-в-точ под другим. При клике мышкой на них, какой отреагирует?

Про какие клубы вы говорите, я ни в какие клубы не записывался и не собираюсь ))

p.s. можете показать пример?

Вообще, в такой ситуации должен отреагировать тот объект, который последним был перемещён - он же наверху...

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