Угол окна привязки и экранные координаты

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

Идентификатор

Описание

Тип

OBJPROP_CORNER

Угол графика для привязки графического объекта

ENUM_BASE_CORNER

OBJPROP_XDISTANCE

Дистанция в пикселях по оси X от угла привязки

int

OBJPROP_YDISTANCE

Дистанция в пикселях по оси Y от угла привязки

int

Допустимые варианты для OBJPROP_CORNER сведены в перечисление ENUM_BASE_CORNER.

Идентификатор

Расположение центра координат

CORNER_LEFT_UPPER

Левый верхний угол окна

CORNER_LEFT_LOWER

Левый нижний угол окна

CORNER_RIGHT_LOWER

Правый нижний угол окна

CORNER_RIGHT_UPPER

Правый верхний угол окна

По умолчанию используется левый верхний угол.

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

Расположение объектов с привязкой к разным углам основного окна

Расположение объектов с привязкой к разным углам основного окна

Все 4 объекта в данный момент выделены на графике, поэтому их точки привязки подсвечиваются контрастным цветом.

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

На следующем рисунке показаны аналогичные объекты в подокне, с привязкой к углам подокна.

Расположение объектов с привязкой к разным углам подокна

Расположение объектов с привязкой к разным углам подокна

С помощью скрипта ObjectCornerLabel.mq5 пользователь может протестировать перемещение текстовой надписи, для которой угол привязки в окне задается во входном параметре Corner.

#property script_show_inputs
   
input ENUM_BASE_CORNER Corner = CORNER_LEFT_UPPER;

Координаты периодически изменяются и выводятся в тексте самой надписи. Таким образом, надпись перемещается в окне и при достижении границы отскакивает от неё. Объект создается в том окне или подокне, куда скрипт был брошен мышью.

void OnStart()
{
   const int t = ChartWindowOnDropped();
   const string legend = EnumToString(Corner);
   
   const string name = "ObjCornerLabel-" + legend;
   int h = (int)ChartGetInteger(0CHART_HEIGHT_IN_PIXELSt);
   int w = (int)ChartGetInteger(0CHART_WIDTH_IN_PIXELS);
   int x = w / 2;
   int y = h / 2;
   ...

Для корректного позиционирования мы узнаем размеры окна (и далее проверяем, не изменились ли они) и находим середину для начального размещения объекта: переменные с координатами — x и y.

Далее мы создаем и настраиваем надпись, пока без координат. Важно отметить, что мы включаем возможность выделять объект (OBJPROP_SELECTABLE) и выделяем его (OBJPROP_SELECTED), так как это позволяет увидеть точку привязки на самом объекте, до которой и отсчитывается расстояние от угла окна (центра координат). Более подробно данные два свойства описаны в разделе Управление состоянием объекта.

   ObjectCreate(0nameOBJ_LABELt00);
   ObjectSetInteger(0nameOBJPROP_SELECTABLEtrue);
   ObjectSetInteger(0nameOBJPROP_SELECTEDtrue);
   ObjectSetInteger(0nameOBJPROP_CORNERCorner);
   ...

В переменных px и py будем записывать приращения координат для эмуляции движения. Сама модификации координат будет производиться в бесконечном цикле, пока его не прервет пользователь. Счетчик итераций позволит периодически, на каждой 50 итерации, случайным образом менять направление движения.

   int px = 0py = 0;
   int pass = 0;
   
   for( ;!IsStopped(); ++pass)
   {
      if(pass % 50 == 0)
      {
         h = (int)ChartGetInteger(0CHART_HEIGHT_IN_PIXELSt);
         w = (int)ChartGetInteger(0CHART_WIDTH_IN_PIXELS);
         px = rand() * (w / 20) / 32768 - (w / 40);
         py = rand() * (h / 20) / 32768 - (h / 40);
      }
   
      // отскок от границ окна, чтобы объект не скрылся
      if(x + px > w || x + px < 0px = -px;
      if(y + py > h || y + py < 0py = -py;
      // пересчитываем позиции надписи
      x += px;
      y += py;
      
      // обновляем координаты объекта и вносим их в текст
      ObjectSetString(0nameOBJPROP_TEXTlegend
         + "[" + (string)x + "," + (string)y + "]");
      ObjectSetInteger(0nameOBJPROP_XDISTANCEx);
      ObjectSetInteger(0nameOBJPROP_YDISTANCEy);
   
      ChartRedraw();
      Sleep(100);
   }
   
   ObjectDelete(0name);
}

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

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