Еще раз. Взаимное расположение графических объектов (МТ4/МТ5)

 

Вынужден вернуться к теме о взаимном расположении графических объектов на графике торгового терминала МТ4 (МТ5).

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

Эту возможность, известную еще как Z-последовательность, предоставляли встроенные в язык MQL4 ресурсы.

Суть ее состоит в том, что графические объекты (старые и вновь создаваемые) автоматически занимали слои в соответствии с алфавитным расположением своих имен, а именно, из двух графических объектов сверху располагался тот, чье имя находилось ближе к концу алфавита. Например, объект с именем «bobject“ располагался выше объекта „aobject“ и мог его перекрывать (частично или полностью) при их совмещении на графике.

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

Приведу пример. Для упорядочивания графических объектов при открытии нового ордера есть один единственный способ. Мне пришлось бы уничтожать пару сотен объектов, а после этого их же создавать вновь (разумеется, вместе с объектами для нового ордера) в требуемой последовательности. Это весьма непривлекательный непрофессиональный подход. Кроме того, он не на 100% применим, поскольку у меня есть потребность располагать объекты по слоям не по времени их появления, а по типам (фон, текст, сигнальная линия и пр.)

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

Как же так?

Подскажите тогда другой, пусть сложный (или очень сложный) способ упорядочения графических объектов. Без этого никак… Или верните Z-последовательность взад.

Спасибо за содействие. 

 
dokpiknik:

Подскажите тогда другой, пусть сложный (или очень сложный) способ упорядочения графических объектов. Без этого никак…

"уничтожать пару сотен объектов, а после этого их же создавать вновь"
 
sergeev:
"уничтожать пару сотен объектов, а после этого их же создавать вновь"


Удо-о-обно! Хота это и не новый метод. Тем не менее спасибо, улыбнули...
 

А это.. извините господа, что вмешиваюсь. Свойство "selectable" в мт4 действует? Не пробовал пока.

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

 
Integer:

А это.. извините господа, что вмешиваюсь. Свойство "selectable" в мт4 действует? Не пробовал пока.

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


Извинение не принимается :). Просто рад снова видеть, Integer!

 Свойство "selectable" в мт4 действует, ура! Проверено и используется мной.

 
Только проблемы это свойство к сожалению не решает.
 

Весьма интересно о порядке создания объектов.

1. сначала размещаю на графике фон "Canvas" (OBJ_RECTANGLE_LABEL),
2. на него кидаю текстовый объект "Risk" (OBJ_LABEL).

По задумке, по щелчку на объекте "Risk" должно появиться поле ввода нового значения переменной Risk. Но в OnChartEvent() упорно возвращается имя объекта "Canvas" в переменной sparam.

Получается, что объект "Risk", помещённый на "Canvas" на самом деле скрыт объектом "Canvas", т.е., находится под ним. Но на графике виден. Свойству OBJPROP_ZORDER объекта "Canvas" задан 0. Объекту "Risk" свойству OBJPROP_ZORDER задано значение 100.

Как только "Risk" помещаю не на "Canvas", нажатия мышки на нём (на Risk) возвращают имя этого объекта, и я могу уже с ним работать дальше.

Вот как сиё понимать?

 
artmedia70:

Вот как сиё понимать?


в МТ4 есть OBJ_RECTANGLE_LABEL ?
 
sergeev:

в МТ4 есть OBJ_RECTANGLE_LABEL ?
//+------------------------------------------------------------------+
   void CGraphClass::SetCanvasBox(const long chart_ID=0,              // ID графика
                     const string           name="RectLabel",         // имя метки
                     const int              sub_window=0,             // номер подокна
                     const int              x=0,                      // координата по оси X
                     const int              y=0,                      // координата по оси Y
                     const int              width=50,                 // ширина
                     const int              height=18,                // высота
                     const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // угол графика для привязки
                     const ENUM_ANCHOR_POINT anchor=ANCHOR_LEFT_UPPER,// точка привязки в левом верхнем углу
                     const color            back_clr=C'236,233,216',  // цвет фона
                     const ENUM_BORDER_TYPE border=BORDER_SUNKEN,     // тип границы
                     const color            clr=clrRed,               // цвет плоской границы (Flat)
                     const ENUM_LINE_STYLE  style=STYLE_SOLID,        // стиль плоской границы
                     const int              line_width=1,             // толщина плоской границы
                     const bool             back=false,               // на заднем плане
                     const bool             selection=false,          // выделить для перемещений
                     const bool             hidden=true,              // скрыт в списке объектов
                     const string           tooltip="\n",             // описание
                     const long             z_order=0)                // приоритет на нажатие мышью
     {
   //--- создадим прямоугольную метку
      if(ObjectFind(name)<0) ObjectCreate(chart_ID,name,OBJ_RECTANGLE_LABEL,sub_window,0,0);
   //--- установим координаты метки
      ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
      ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
   //--- установим размеры метки
      ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
      ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
   //--- установим цвет фона
      ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
   //--- установим тип границы
      ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_TYPE,border);
   //--- установим угол графика, относительно которого будут определяться координаты точки
      ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
   //--- установим положение точки привязки
      ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
   //--- установим цвет плоской рамки (в режиме Flat)
      ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
   //--- установим стиль линии плоской рамки
      ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
   //--- установим толщину плоской границы
      ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,line_width);
   //--- отобразим на переднем (false) или заднем (true) плане
      ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
   //--- включим (true) или отключим (false) режим перемещения метки мышью
      ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
      ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
   //--- скроем (true) или отобразим (false) имя графического объекта в списке объектов
      ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
   //--- зададим описание объекта (tooltip)
      ObjectSetString(chart_ID,name,OBJPROP_TOOLTIP,tooltip);
   //--- установим приоритет на получение события нажатия мыши на графике
      ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
   //--- успешное выполнение
   }
//+------------------------------------------------------------------+
 
artmedia70:

в меню нет.



тот прямоугольник что есть - никакого конфликта не делает.

то видать либо неверное создание и баг в МТ

 
artmedia70:

Весьма интересно о порядке создания объектов.

1. сначала размещаю на графике фон "Canvas" (OBJ_RECTANGLE_LABEL),
2. на него кидаю текстовый объект "Risk" (OBJ_LABEL).

По задумке, по щелчку на объекте "Risk" должно появиться поле ввода нового значения переменной Risk. Но в OnChartEvent() упорно возвращается имя объекта "Canvas" в переменной sparam.

Получается, что объект "Risk", помещённый на "Canvas" на самом деле скрыт объектом "Canvas", т.е., находится под ним. Но на графике виден. Свойству OBJPROP_ZORDER объекта "Canvas" задан 0. Объекту "Risk" свойству OBJPROP_ZORDER задано значение 100.

Как только "Risk" помещаю не на "Canvas", нажатия мышки на нём (на Risk) возвращают имя этого объекта, и я могу уже с ним работать дальше.

Вот как сиё понимать?

Правило, касающееся доступа графических объектов для клика мыши при совмещенности объектов, которое существовало и во времена Z-последовательности, таково: для клика мыши доступен самый нижний объект. Так что все правильно.

С помощью z-ордера можно это "правило кликабельности объектов" изменять. Однако, это не меняет картинку, а именно, какие объекты видно, а какие перекрыты.