A lona é legal! - página 84

 
Martin Moreno #:
Quero criar uma interface de usuário com a classe Canvas. Meu único problema é que não sei como tornar o painel móvel no gráfico.
Pesquisei muito, mas não encontrei nenhum exemplo. Agradeceria se você pudesse dar uma dica.


Você poderia começar por este artigo: https: //www.mql5.com/en/articles/12751

Improve Your Trading Charts With Interactive GUI's in MQL5 (Part I): Movable GUI (I)
Improve Your Trading Charts With Interactive GUI's in MQL5 (Part I): Movable GUI (I)
  • www.mql5.com
Unleash the power of dynamic data representation in your trading strategies or utilities with our comprehensive guide on creating movable GUI in MQL5. Dive into the core concept of chart events and learn how to design and implement simple and multiple movable GUI on the same chart. This article also explores the process of adding elements to your GUI, enhancing their functionality and aesthetic appeal.
 
Samuel Manoel De Souza #:

Você poderia começar por este artigo: https: //www.mql5.com/en/articles/12751

Ótimo... Muito obrigado!

 
Martin Moreno #:
Quero criar uma interface de usuário com a classe Canvas. Meu único problema é que não sei como tornar o painel móvel no gráfico.
Pesquisei muito, mas não encontrei nenhum exemplo. Agradeceria se você pudesse dar uma dica.


Eu já lhe dei um exemplo há 4 anos :))

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Como converter todos os objetos em um único objeto?

Nikolai Semko, 2019.10.05 22:39

De fato, o Canvas é a solução.

E o Canvas é muito mais fácil do que parece à primeira vista.

Aqui está um exemplo primitivo de um indicador (MQL5 e MQL4) com um objeto OBJ_BITMAP_LABEL no qual há muitas janelas.

#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();
}
//+------------------------------------------------------------------+

Neste novo artigo, outra opção para implementar painéis de informações.

https://www.mql5.com/ru/articles/13179

Arquivos anexados:
 
Nikolai Semko #:
Aqui, por exemplo, esbocei um script que demonstra isso claramente. À direita está esse algoritmo rápido, e à esquerda está o meu (cerca de 4 a 10 vezes mais lento).
.
Nikolai Semko, olá. Neste exemplo https://www.mql5.com/ru/forum/227736/page66#comment_20456641 você demonstrou o redimensionamento (encolhimento) de Bmp.

Posso reduzir a imagem Bmp, mas a tela permanece do mesmo tamanho. Pelo mesmo motivo, não posso ampliar a imagem, pois ela é cortada no tamanho original, ou seja, no tamanho da tela.

Não entendo muito bem de arrays, então você poderia me explicar ou, melhor ainda, mostrar um exemplo com código:

1. Ampliação da imagem

2. Uma tela igual ao tamanho da imagem, se a tivermos reduzido ou ampliado.

Obrigado.

 
Vitaliy Kuznetsov #:
Nikolai Semko, olá. Neste exemplo https://www.mql5.com/ru/forum/227736/page66#comment_20456641, você demonstrou o redimensionamento (redução) de Bmp.

Posso reduzir a imagem Bmp, mas a tela permanece do mesmo tamanho. Pelo mesmo motivo, não posso ampliar a imagem, pois ela é cortada no tamanho original, ou seja, no tamanho da tela.

Não entendo muito bem de arrays, então você poderia me explicar ou, melhor ainda, mostrar um exemplo com código:

1. Ampliação da imagem

2. Uma tela igual ao tamanho da imagem, se a tivermos reduzido ou ampliado.

Obrigado.

Hi,
Há uma função Resize() no CCanvas.
 
Vitaliy Kuznetsov #:

Legal e útil. Só por curiosidade, isso pode ser usado no MT4?

Infelizmente, na MQL4 não há possibilidade de anexar um recurso como uma matriz. Mas todo o resto funciona.
É claro que isso pode ser implementado por meio de pandeiros rígidos. Por exemplo, insira uma imagem PNG em um arquivo BMP, ou seja, adicione um cabeçalho BMP ao início do png e passe o próprio png como uma imagem bmp (ou seja, se você abrir esse BMP, haverá um ruído de pixels coloridos de transparência diferente). E, em seguida, anexe esse "arquivo bmp" como um recurso em MQL4. Isso pode ser necessário para o mercado, de modo que o ex4 já contenha uma imagem de um formato png mais denso.
Para referência: png é cerca de 10 vezes menor do que a mesma imagem BMP sem perda de qualidade, além de suportar transparência total.
O verdadeiro recurso bmp no arquivo ex5(ex4) é armazenado em um formato compactado, mas não em uma ordem de magnitude menor. É necessário verificar com exatidão.
 

Bom dia a todos. Também estou interessado nesse código. Mas ao usar Resize(), ele não funciona. Talvez isso deva ser feito em uma sequência diferente.

 
Vladimir Nikolaychuk #:

Bom dia a todos. Também estou interessado nesse código. Mas ao usar Resize(), ele não funciona. Talvez isso deva ser feito em uma sequência diferente.

Ok, vou lhe dar um exemplo mais tarde.
Mas eu prefiro trabalhar com uma tela para todo o gráfico. Isso se justifica em 95% das vezes.
 
Nikolai Semko #:
Ok, vou lhe dar um exemplo mais tarde.
Mas eu prefiro trabalhar com uma tela para todo o gráfico. Isso se justifica em 95% das vezes.

Ficaria muito grato se me enviasse um exemplo de código. Desde já, obrigado...

 
Nikolai Semko #:
Ok, vou lhe dar um exemplo mais tarde.
Mas eu prefiro trabalhar com uma tela para todo o gráfico. Isso se justifica em 95% das vezes.

Aqui está um exemplo baseado na biblioteca png.mql, quando o movimento do mouse muda a posição da tela e altera seu tamanho. Se o ponteiro do mouse estiver no centro horizontalmente, ele corresponderá ao tamanho original da imagem; se estiver à esquerda, diminuirá o zoom; se estiver à direita, aumentará o zoom.
Só que tive de alterar as variáveis C e _C em png.mql de privadas para públicas. Portanto, você precisa sobrescrever essa biblioteca se ela já estiver instalada.
Esse exemplo tem dois modos de operação (variável de entrada bool resize_canvas):

  • com redimensionamento do Canvas toda vez que a imagem é redimensionada
  • sem redimensionar o Canvas toda vez que a imagem for redimensionada. O tamanho inicial do Canvas é definido como o tamanho máximo possível da imagem, de acordo com a lógica de trabalho.
Infelizmente, no primeiro modo em MQL5 há um bug antigo de imagem piscando, que pode ser curado apenas de uma maneira - não alterar o tamanho da tela. Todas as minhas tentativas de alterar a função CCanvas.Resize() não levaram a nada. Tudo pisca da mesma forma. Talvez alguém consiga fazer isso :)))
É por isso que prefiro usar uma tela para toda a tela!

#define  MAX_ZOOM 2
#include <Canvas\png.mqh> //https://www.mql5.com/en/code/45439
CPng img("cubes.png"); // Get PNG from a file, create a canvas and display it on the screen at coordinates (X=500, Y=100)

input bool resize_canvas = false;
int chart_width,chart_height;


//+------------------------------------------------------------------+
int OnInit() {
   img.Resize(resize_canvas?10:img.width*MAX_ZOOM); // формируем массив _bmp[] максимального размера в режиме без изменения размера canvas
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
   chart_width = (int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
   chart_height = (int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
   img._CreateCanvas(chart_width/3, chart_height/3);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
}
//+------------------------------------------------------------------+
void OnTick() {
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam) {
   if (id == CHARTEVENT_MOUSE_MOVE) {
      double new_width = img.width*(MAX_ZOOM*(double)lparam/chart_width);
      img.Resize(new_width);
      if (resize_canvas) { // режим с изменением размера canvas  Моргает!!!
         img._C.Resize(img._width,img._height);
         ArrayCopy(img._C.m_pixels,img._bmp);
      } else {  // режим без изменения размера canvas         не Мограет!!!
         img._C.Erase(0x00FFFFFF);
         for(int i =0; i++<img._height;) ArrayCopy(img._C.m_pixels,img._bmp,int(i*img.width*MAX_ZOOM),i*img._width,img._width);
      }
      img._C.Update();
      img._MoveCanvas(int(lparam)/5, int(dparam)/5);
   }
}



PNG
PNG
  • www.mql5.com
Forget about BMP files like a bad dream. Thanks to this library, you can now use the PNG format, which has a number of advantages, such as being more compact without losing image quality and maintaining transparency.
Arquivos anexados:
Razão: