Prevent Chart Receiving Events when a Dialog is Open

 

How do I stop the main chart from receiving events when a dialog window is open? When a user click/drags over the dialog window, as they would to interact with controls on the panel the event gets passed to the chart behind. Obviously this is undesirable if the chart has chart objects on the chart such as VLINES, HLINES, because the object could get moved unintentionally by the action intended for the dialog window.

Thank you.

 
What "dialog window" are you talking about ? A custom one from your code ?
 
robnorthen:

How do I stop the main chart from receiving events when a dialog window is open? When a user click/drags over the dialog window, as they would to interact with controls on the panel the event gets passed to the chart behind. Obviously this is undesirable if the chart has chart objects on the chart such as VLINES, HLINES, because the object could get moved unintentionally by the action intended for the dialog window.

Thank you.

The main problem with a click that is on your dialog is if there is a selected object behind it on the chart .

You could loop and deselect all objects when your dialog comes up . 

If you want to prevent object selection , you could also place an "invisible" wall between the user and the chart so the objects cannot be selected

If you want to take it to an extreme level you could grab a screenshot of the chart , process it, blur it and paint a blurred "glass" between the dialog and the chart .

here is a basic test . However , if your dialog is permanent and does not take up your entire screen you could deselect all objects once a click hits the dialog . I don't know how annoying this would turn out to be for the user though . 

#property version   "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
string system_tag="TEST_";
bool curtain_up=false;
int OnInit()
  {
//---
  ObjectsDeleteAll(ChartID(),system_tag);
  //button to raise dialog (custom one)
  ObjectCreate(ChartID(),system_tag+"_BUTTON",OBJ_BUTTON,0,0,0);
  ObjectSetInteger(ChartID(),system_tag+"_BUTTON",OBJPROP_YDISTANCE,20);
  //place some objects on the chart manually
  curtain_up=false;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam)
  {
  if(id==CHARTEVENT_OBJECT_CLICK&&sparam==system_tag+"_BUTTON"){
    CurtainUp();
    //create dialog after call function , now i just throw a rectangle
    ObjectCreate(ChartID(),system_tag+"_Dialog",OBJ_RECTANGLE_LABEL,0,0,0);
    ObjectSetInteger(ChartID(),system_tag+"_Dialog",OBJPROP_BGCOLOR,clrPink);
    ObjectSetInteger(ChartID(),system_tag+"_Dialog",OBJPROP_XSIZE,200);
    ObjectSetInteger(ChartID(),system_tag+"_Dialog",OBJPROP_YSIZE,300);
    ObjectSetInteger(ChartID(),system_tag+"_Dialog",OBJPROP_XDISTANCE,30);
    ObjectSetInteger(ChartID(),system_tag+"_Dialog",OBJPROP_YDISTANCE,30);
    }else if(id==CHARTEVENT_CHART_CHANGE&&curtain_up){
    CurtainUp();
    }
  }
  
void CurtainUp(){
//unselect all objects
  for(int i=0;i<ObjectsTotal(ChartID(),0);i++){
  ObjectSetInteger(ChartID(),ObjectName(ChartID(),i,0),OBJPROP_SELECTED,false);
  }
int wid=(int)ChartGetInteger(ChartID(),CHART_WIDTH_IN_PIXELS,0);
int hei=(int)ChartGetInteger(ChartID(),CHART_HEIGHT_IN_PIXELS,0);
uint pixels[];
ArrayResize(pixels,wid*hei,0);
ArrayFill(pixels,0,ArraySize(pixels),0);
ResourceFree("::CURTAIN");
ResourceCreate("CURTAIN",pixels,wid,hei,0,0,wid,COLOR_FORMAT_ARGB_NORMALIZE);
ObjectCreate(ChartID(),system_tag+"_CURTAIN",OBJ_BITMAP_LABEL,0,0,0);
    ObjectSetInteger(ChartID(),system_tag+"_CURTAIN",OBJPROP_XSIZE,wid);
    ObjectSetInteger(ChartID(),system_tag+"_CURTAIN",OBJPROP_YSIZE,hei);
    ObjectSetInteger(ChartID(),system_tag+"_CURTAIN",OBJPROP_XDISTANCE,0);
    ObjectSetInteger(ChartID(),system_tag+"_CURTAIN",OBJPROP_YDISTANCE,0);
    ObjectSetString(ChartID(),system_tag+"_CURTAIN",OBJPROP_BMPFILE,"::CURTAIN");
curtain_up=true;
ChartRedraw();
}
 
Lorentzos Roussos #:

The main problem with a click that is on your dialog is if there is a selected object behind it on the chart .

You could loop and deselect all objects when your dialog comes up . 

If you want to prevent object selection , you could also place an "invisible" wall between the user and the chart so the objects cannot be selected

If you want to take it to an extreme level you could grab a screenshot of the chart , process it, blur it and paint a blurred "glass" between the dialog and the chart .

here is a basic test . However , if your dialog is permanent and does not take up your entire screen you could deselect all objects once a click hits the dialog . I don't know how annoying this would turn out to be for the user though . 

Thank you for your suggestions. Would this work when the user's SL and TP lines are visible? Recently, when I dragged down on a CListView box in my CAppDialog window, the SL line behind it also dragged down. I prefer your first suggestion, but I don't think there's a way to deselect these lines.

Rob

 
robnorthen #:

Thank you for your suggestions. Would this work when the user's SL and TP lines are visible? Recently, when I dragged down on a CListView box in my CDialog window, the SL line behind it also dragged down. I prefer your first suggestion, but I don't think there's a way to deselect these lines.

Rob

Good observation , i'll check now 

No , there is no protection against dragging the sl / tp . Let me find if there is any switch for the chart 

:: There is a switch to prevent sl/tp dragging , so if you add this 

//disable dragging 
  ChartSetInteger(ChartID(),CHART_DRAG_TRADE_LEVELS,false);

under the deselection of objects loop it will not allow it . 

You will have to store the users choice somewhere though in order to restore it once the curtain falls .

 
Alain Verleyen #:
What "dialog window" are you talking about ? A custom one from your code ?

Yes Alain, a custom CAppDialog window.

 
robnorthen #:

Yes Alain, a custom CAppDialog window.

I see. Interesting issue.
 
Lorentzos Roussos #:

Good observation , i'll check now 

No , there is no protection against dragging the sl / tp . Let me find if there is any switch for the chart 

:: There is a switch to prevent sl/tp dragging , so if you add this 

under the deselection of objects loop it will not allow it . 

You will have to store the users choice somewhere though in order to restore it once the curtain falls .

Perfect! I'll deselect all selected graphic objects and set CHART_DRAG_TRADE_LEVELS to 0 on CAppDialog's Maximise event and then restore on Close or Minimise.

Thank you.

 
robnorthen #:

Perfect! I'll deselect all selected graphic objects and set CHART_DRAG_TRADE_LEVELS to 0 on CAppDialog's Maximise event and then restore on Close or Minimise.

Thank you.

You are welcome 

 
robnorthen #:

Perfect! I'll deselect all selected graphic objects and set CHART_DRAG_TRADE_LEVELS to 0 on CAppDialog's Maximise event and then restore on Close or Minimise.

Thank you.

Does the inherited bringtotop function not do what you need?

I’ve not had this issue with my panels. I’ll check what I did when I’m at a machine