How to move objects inside a panel together with the panel itself?

 

Hi, I'm trying to create a simple panel with texts, colors and dynamic information inside it...

I'm using MQL5's standard library to do most of the tasks, and I'm actually able to create the panel itself and some content inside the panel.

However, when I click and drag the panel with the mouse, only the panel itself is moving, while the labels and background colors inside the panel are fixed.

I'm showing below the code and I really don't know what I'm doing wrong, but I believe it has something to do with the CHARTEVENT_OBJECT_DRAG option inside OnChartEvent().

//╔══════════════════════════════════════════════════════════════════╗
//║                                                      MyPanel.mq5 ║
//║                                                  ■ DeltaTrader ■ ║
//║                                    http://www.deltatrader.com.br ║
//╚══════════════════════════════════════════════════════════════════╝
#property copyright     "DeltaTrader © 2013"
#property link          "www.deltatrader.com.br"
#property version       "1.000"
#property description   "DeltaTrader TEST"

//╔══════════════════════════════════════════════════════════════════╗
//║ INCLUDES ------------------------------------------------------- ║
//╚══════════════════════════════════════════════════════════════════╝
#include <Controls\Dialog.mqh>
#include <Controls\Label.mqh>
#include <Controls\Panel.mqh>
#include <Controls\WndObj.mqh>


//╔══════════════════════════════════════════════════════════════════╗
//║ GLOBAL PARAMETERS ---------------------------------------------- ║
//╚══════════════════════════════════════════════════════════════════╝
int      panelXX     =  20;
int      panelYY     =  20;
int      panelWidth  =  400;
int      panelHeight =  250;


//╔══════════════════════════════════════════════════════════════════╗
//║ GLOBAL VARIABLES ----------------------------------------------- ║
//╚══════════════════════════════════════════════════════════════════╝
//--- Objeto do painel
CAppDialog myPanel;

//--- Objetos do label e background do bid
CPanel BidColor;
CLabel BidLabel;

//--- Objetos do label e background do ask
CPanel AskColor;
CLabel AskLabel;


//╔══════════════════════════════════════════════════════════════════╗
//║ VOIDS & FUNCTIONS ---------------------------------------------- ║
//╚══════════════════════════════════════════════════════════════════╝
void DelAllObjects(string name)
  {
   string vName;
   int tot=ObjectsTotal(0);
   for(int i=tot; i>=0; i--)
     {
      vName=ObjectName(0,i);
      if(StringSubstr(vName,0,StringLen(name))==name) ObjectDelete(0,vName);
     }
  }


//╔══════════════════════════════════════════════════════════════════╗
//║ ON INIT -------------------------------------------------------- ║
//╚══════════════════════════════════════════════════════════════════╝
int OnInit() {
//--- Panel create
   myPanel.Create(0, "TEST PANEL", 0, panelXX, panelYY, panelWidth, panelHeight);

//--- Bid label
   BidColor.Create(0,"Bid Background Color",0,panelXX+5,panelYY+25,panelXX+panelWidth-25,panelYY+45);
   BidColor.ColorBackground(clrYellow);
   BidLabel.Create(0,"Bid Text",0,panelXX+8,panelYY+25,0,0);   
   BidLabel.Text("Bid "+DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits));
   BidLabel.Color(clrBlue);
   
//--- Ask label
   AskColor.Create(0,"Ask Background Color",0,panelXX+5,panelYY+105,panelXX+panelWidth-25,panelYY+125);
   AskColor.ColorBackground(clrAqua);
   AskLabel.Create(0,"Ask Text",0,panelXX+8,panelYY+105,0,0);   
   AskLabel.Text("Ask "+DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits));
   AskLabel.Color(clrRed);

//--- Run panel
   myPanel.Run();   
//--- Define frequência do timer
   EventSetTimer(1);
//--- Return
   return(0);
}


//╔══════════════════════════════════════════════════════════════════╗
//║ ON DEINIT ------------------------------------------------------ ║
//╚══════════════════════════════════════════════════════════════════╝
void OnDeinit(const int reason){
//--- Destroy panel
   myPanel.Destroy(reason);
//--- Destroy bid-related info
   BidLabel.Destroy(reason);
   BidColor.Destroy(reason);
//--- Destroy ask-related info
   AskLabel.Destroy(reason);
   AskColor.Destroy(reason);
//--- Delete all objects
   DelAllObjects("");
//--- Remove timer
   EventKillTimer();
//---   
}


//╔══════════════════════════════════════════════════════════════════╗
//║ ON CALCULATE --------------------------------------------------- ║
//╚══════════════════════════════════════════════════════════════════╝
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//--- Bid label
   BidLabel.Text("Bid "+DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits));
//--- Ask label
   AskLabel.Text("Ask "+DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits));
//---
   return(rates_total);
  }


//╔══════════════════════════════════════════════════════════════════╗
//║ ON CHART EVENT ------------------------------------------------- ║
//╚══════════════════════════════════════════════════════════════════╝
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
//---
   myPanel.ChartEvent(id, lparam, dparam, sparam);
//--- 

//--- o mouse foi clicado sobre o objeto gráfico
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
      //--- Define a variável ClickedChartObject
      string ClickedChartObject=sparam;
      //--- Print
      Print("O mouse foi clicado sobre o objeto com o nome '"+sparam+"'");
      //--- Remove o Expert Advisor no click do mouse
      if( ClickedChartObject == "TEST PANEL" ) //ExpertRemove();
      //---
      panelXX=lparam;
      panelYY=dparam;
      ChartRedraw();
   }
//---
   if(id == CHARTEVENT_OBJECT_DRAG)
   {
      string vName;
      int tot=ObjectsTotal(0);
      for(int i=tot; i>=0; i--)
        {
         vName=ObjectName(0,i);
         panelXX=lparam;
         panelYY=dparam;

        }
      
      Print("O ponto de ancoragem das coordenadas do objeto com o nome ",sparam," foi alterado");
      //---
      panelXX=lparam;
      panelYY=dparam;
      ChartRedraw();      
   }
//---  
}

I trully appreciate any help! Thanks! 

Documentation on MQL5: Standard Constants, Enumerations and Structures / Chart Constants / Types of Chart Events
Documentation on MQL5: Standard Constants, Enumerations and Structures / Chart Constants / Types of Chart Events
  • www.mql5.com
Standard Constants, Enumerations and Structures / Chart Constants / Types of Chart Events - Documentation on MQL5
 

1. I noticed that in the OnChartEvent handler you modified the values of panelXX and panelYY and call ChartRedraw().

    But it won't move the objects because after the objects were created, there is no relationship between panelXX/panelYY and the objects' coordinates.

2. The Standard Control classes can handle the mouse events very well and you don't have to do it by yourself. The first line in your code is already enough to handle the OnChartEvent. That's the reason why you can move the panel successfully :)

3. The trick is that you need to add the "BidColor", "BidLabel", "AskColor" and "AskLabel" as the child controls of the "myPanel". This can be done by the "myPanel.Add()" function. I modified your code a little for your reference:

int OnInit() {
//--- Panel create
   myPanel.Create(0, "TEST PANEL", 0, panelXX, panelYY, panelWidth, panelHeight);

//--- Bid label
   BidColor.Create(0,"Bid Background Color",0,5,25,panelWidth-45,45);
   BidColor.ColorBackground(clrYellow);
   myPanel.Add(BidColor);
   BidLabel.Create(0,"Bid Text",0,8,25,0,0);   
   BidLabel.Text("Bid "+DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits));
   BidLabel.Color(clrBlue);
   myPanel.Add(BidLabel);
   
//--- Ask label
   AskColor.Create(0,"Ask Background Color",0,5,105,panelWidth-45,125);
   AskColor.ColorBackground(clrAqua);
   myPanel.Add(AskColor);
   AskLabel.Create(0,"Ask Text",0,8,105,0,0);   
   AskLabel.Text("Ask "+DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits));
   AskLabel.Color(clrRed);
   myPanel.Add(AskLabel);

//--- Run panel
   myPanel.Run();   
//--- Define frequência do timer
   EventSetTimer(1);
//--- Return
   return(0);
}

 The highlighted part is my modification. They simply did the following:

1. Change the label and the background coordinates to relative coordinates (remove the panelXX, panelYY), modify the panelWidth-25 to panelWidth-45, otherwise it is too wide to fit in the myPanel dialog box.

2. Call myPanel.Add() to add the controls as myPanel's child controls.

And the OnChartEvent() can be modified as simple as:

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
//---
   myPanel.ChartEvent(id, lparam, dparam, sparam);
//--- 
}

I tested the modified code in my environment and it works fine :) 

Documentation on MQL5: Chart Operations / ChartRedraw
Documentation on MQL5: Chart Operations / ChartRedraw
  • www.mql5.com
Chart Operations / ChartRedraw - Documentation on MQL5
 
BTW, under "[Your MT5 Folder]\MQL5\Experts\Examples\Controls", you may find some useful sample code on how to use controls in the MQL5 Standard Library. FYI.
Documentation on MQL5: Standard Library
Documentation on MQL5: Standard Library
  • www.mql5.com
Standard Library - Documentation on MQL5
 

Such a fast and high-level answer is exactly what makes this community so professional !!!

Thanks a lot, Jian! Works perfectly !!!

Reason: