Improve Your Trading Charts With Interactive GUI's in MQL5 (Part I): Movable GUI (I)
Introduction
Welcome to the exciting world of movable GUI in MQL5! This guide is here to empower you with the knowledge to create dynamic, interactive GUI that will elevate your trading strategies. We'll start by decoding the essential concept of chart events, the engine driving our GUI interactivity. With this foundation, we'll then guide you through crafting your first movable GUI.
Then in the next part, we will advance to creating multiple GUI on a single chart efficiently (not just by copy pasting stuff), we'll delve into enhancing our GUI by adding and customizing various elements, tailoring it to your unique needs. We've also catered to those eager to dive right in with a streamlined guide offering quick steps to make your GUI movable.
By the end of this journey, you'll have gained a valuable skill in creating and manipulating movable GUI in MQL5, a powerful tool for any trader. Even if you're in a hurry, we've got you covered with a quick-guide section for those who want to jump right into making their GUI movable. So, let's get started on this exciting journey!
We will be proceeding further in the following manner:
- Decoding Chart Events: The Building Blocks of Movable GUI
- Crafting Your First Movable GUI: A Step-by-Step Guide
- Conclusion
Decoding Chart Events: The Building Blocks of Movable GUI
As of now, the EA Code looks like this i.e. absolute basic EA:
You might be wondering why EA, why not Indicator? Well, The reason for that is EA is easier to understand for most peoples while Indicator may confuse some but rest assured, Same steps can be followed in Indicator too.
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- 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) { //--- } //+------------------------------------------------------------------+
Now, To understand OnChartEvent better, Let's compare it with other predefined function that you already know about from the above absolute basic EA with OnChartEvent().
Predefined functions | Their Roles |
---|---|
OnInit() | Run On Initialization i.e. The EA is Initialized (Attached) on the chart, This runs only once |
OnTick() | Run On Tick i.e. When Symbol on the chart receives a tick from the broker, tick means price update |
OnDeinit() | Run On Deinitialization i.e. The EA is Deinitialized (Removed) from the chart, This runs only once |
In the same manner OnChartEvent() is a function that is executed when certain events happen. Well, What events are we talking about here?
There are 9 predefined events (excluding 2 custom onces):
- CHARTEVENT_KEYDOWN
- CHARTEVENT_MOUSE_MOVE
- CHARTEVENT_OBJECT_CREATE
- CHARTEVENT_OBJECT_CHANGE
- CHARTEVENT_OBJECT_DELETE
- CHARTEVENT_CLICK
- CHARTEVENT_OBJECT_CLICK
- CHARTEVENT_OBJECT_DRAG
- CHARTEVENT_OBJECT_ENDEDIT
Brief Overview for the once that we will be using later on in the article:
- CHARTEVENT_KEYDOWN
When chart window is in focus (just click anywhere on the chart window to get it in focus) OnChartEvent() function is executed each time any key on the keyboard is clicked, to be specific key is pressed down
Holding it will mean clicking the key again and again at a rate of 30 Clicks per second.
On that key is pressed what can we do about it, NOT MUCH. It is useless untill we know what key is pressed, Then How do we know what key was pressed? Well that's where Parameters of OnChartEvent() comes into the play.
What parameters are we talking about? There are 4 parameter we get when OnChartEvent() is executed
- id -> integer
- lparam -> long
- dparam -> double
- sparam -> string
These are simply put, Some data about the events for which OnChartEvent() is called for and We can use this data inside OnChartEvent() function.
For example In case on event CHARTEVENT_KEYDOWN,
- id contains CHARTEVENT_KEYDOWN itself so that we can identify for what event the OnChartEvent() is called for and treat the othere params accordingly.
- lparam contains keycode of the key pressed.
- dparam contains number of keypresses generated while the key was held in the pressed state but when we hold the key it does not set the key in pressed state and instead does 30 clicks per second. So, This value is always 1.
- sparam contains bit mask, simply put It desctibes the state of the key, pressed or clicked by showing 2 different values for a specific key (see the example below to understand it better).
Say we clicked/hold key "A" on the keyboard then OnChartEvent() will be executed with- id = CHARTEVENT_KEYDOWN
- lparam = 65
- dparam = 1
- sparam = 30 for first click and 16414 for the continuous subsequent clicks while holding A at the rate of 30 Clicks per second.
Now that we have the information, we can use some if statements and do something when user press or holds A key.
-
CHARTEVENT_MOUSE_MOVE
First of all it requires a booleon chart property names CHART_EVENT_MOUSE_MOVE to be set to True, It can simply be done by using a simple line of code://Set Chart property CHART_EVENT_MOUSE_DOWN to true ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
It is usually recommended to do this on OnInit(), Once this is done we can use CHARTEVENT_MOUSE_MOVE
Whenever Mouse is moved above the chart, OnChartEvent() will be executed with below information in the params:
- id = CHARTEVENT_MOUSE_MOVE
- lparam = x-axis co-ordinate
- dparam = y-axis co-ordinate
- sparam = bit mask, which describes the state of the mouse keys
bitmask holds below values ->
- Mouse Left --> 1
- Mouse Right --> 2
- Mouse Middle --> 16
- Mouse First X Key --> 32
- Mouse Second X Key --> 64
- Shift Key --> 4
- Control Key --> 8
Chart window is on 4th quadrant i.e. x-axis co-ordinate (lparam) is from Left of the chart window and y-axis co-ordinate (dparam) from Top the chart window. Now With all that information, we are ready to use CHARTEVENT_MOUSE_MOVE, We will be using it below to make GUI movable.
-
CHARTEVENT_CLICK
It does not require any special property, We can use it directly i.e. Whenever mouse is clicked on the chart, OnChartEvent() is executed with below params- id = CHARTEVENT_CLICK
- lparam = x-axis co-ordinate
- dparam = y-axis co-ordinate
- sparam = "" i.e. empty string that means it doesn't provide any useful information
Now that we have the above information, we can use some if statements and do something when user clicks anywhere on the chart.
Above We have discussed 3 events that executes OnChartEvent() fundtion, CHARTEVENT_KEYDOWN, CHART_EVENT_MOUSE_MOVE, CHARTEVENT_CLICK
I know if you have not used OnChartEvent() function before, All of this may seem bit confusing and overwhelming, Well have been there but We all have gotten out of that stage too by learning more and practicing more. We Will be Practicing the above knowledge below to make GUI movvable, Stick with me and you will feel confident and better very soon.
Read Documentation or Comment down below if you need details for the other events that execute OnChartEvent().
Crafting Your First Movable GUI: A Step-by-Step Guide
Now that all the boring stuff is done, We can focus on Real Learning i.e. Applying the theory that we learned to do real stuff not just talking
So In this section Our goal is to create a very very simple looking GUI or we can say a Blank White Rectangle Label. Now now don't get demotivated just because we are not creating complex good looking GUI, things always start from the basics but they increase their level exponentially.
Do you think you can keep up with it? Try it to find out, Stick with me till the end of this article and see if you can say that all of this was easy. Let's call this GUI a dashboard as soon we will make it a dashboard. So, Let's get started with it without any further ado
First, Let's create a Basic Rectangle Label of 200x200 (XSize x YSize) at 100 pixels from Left (XDistance) and 100 pixels from Top (YDistance)
int OnInit() { //--- //Set the name of the rectangle as "TestRectangle" string name = "TestRectangle"; //Create a Rectangle Label Object at (time1, price1)=(0,0) ObjectCreate(0, name, OBJ_RECTANGLE_LABEL, 0, 0, 0); //Set XDistance to 100px i.e. Distance of Rectangle Label 100px from Left of the Chart Window ObjectSetInteger(0, name,OBJPROP_XDISTANCE, 100); //Set YDistance to 100px i.e. Distance of Rectangle Label 100px from Top of the Chart Window ObjectSetInteger(0, name,OBJPROP_YDISTANCE, 100); //Set XSize to 200px i.e. Width of Rectangle Label ObjectSetInteger(0, name,OBJPROP_XSIZE, 200); //Set YSize to 200px i.e. Height of Rectangle Label ObjectSetInteger(0, name,OBJPROP_YSIZE, 200); //--- return(INIT_SUCCEEDED); }
Now when we attach the EA to chart we should see our created Rectangle Label like:
Figure 1.Simple Rectangle Label
Now If we can make this movable with mouse drag then we can do a lot of things like move a very complex multiple dashboard freely on the chart window which can make very good interactive EA's/Indicator's, One of the best application for this can be seen Trade Assistant EA.
So How do we proceed for making it movable? Let's create a plan first:
- Conditions before moving it:
-
Mouse must be on the dashboard
-
Mouse Left button must be down
-
- Then If we move our mouse while holding Mouse Left button down, the dashboard should be moving
- But How much should it move?, It should move exactly as much as mouse has moved from the point mouse has satisfied both it's conditon.
So, That is a basic overview of our plan to make it movable, Now Let's code it step by step:
For the first condition, Mouse must be on the dashboard, We first need to find x and y co-ordinates of mouse position
Time to apply the theory, For x and y axes co-ordinate of mouse, We need to use OnChartEvent(), what do we do next? Try to remember.
- We set Chart Property, CHART_EVENT_MOUSE_MOVE to True
We put the below code in OnInit() to make it true when EA is initialized:
//Set Chart property CHART_EVENT_MOUSE_DOWN to true ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
- Now we can get mouse co-ordinate in OnChartEvent()
void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam) { //Verify the event that triggered the OnChartEvent was CHARTEVENT_MOUSE_MOVE because we only want to execute out code when that is the case if(id == CHARTEVENT_MOUSE_MOVE) { //Comment the X and Y Axes Coordinates Comment("X: ", lparam, "\nY: ", dparam); } }
In OnChartEvent(), First we verify that the event that triggered the OnChartEvent was CHARTEVENT_MOUSE_MOVE using a simple if statement that check if the id is equal to CHARTEVENT_MOUSE_MOVE because we only want to execute our comment code when that is the case
Then we comment the X and Y Axes Coordinate (It will show on left top corner of the chart window in white color with a bit small font) like:
Figure 2. X,Y Coordinate Comment
Now For our logic to find out if the mouse is on dashboard, see the below image:
Figure 3. Formula Visualization
To find out if the mouse is on dashboard,
- X >= XDistance --> X>=100
- X <= XDIstance + XSize --> X<=300
- Y >= YDistance --> Y>=100
- Y <= YDistance + YSize --> Y>=300
Converting into code:
void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam) { //Verify the event that triggered the OnChartEvent was CHARTEVENT_MOUSE_MOVE because we only want to execute out code when that is the case if(id == CHARTEVENT_MOUSE_MOVE) { //define X, Y, XDistance, YDistance, XSize, YSize int X = (int)lparam; int Y = (int)dparam; string name = "TestRectangle"; int XDistance = ObjectGetInteger(0, name, OBJPROP_XDISTANCE); //Should be 100 initially as we set it in OnInit() int YDistance = ObjectGetInteger(0, name, OBJPROP_YDISTANCE); //Should be 100 initially as we set it in OnInit() int XSize = ObjectGetInteger(0, name, OBJPROP_XSIZE); //Should be 200 initially as we set it in OnInit() int YSize = ObjectGetInteger(0, name, OBJPROP_YSIZE); //Should be 200 initially as we set it in OnInit() //Check Mouse on Dashboard condition if(X >= XDistance && X <= XDistance + XSize && Y >= YDistance && Y <= YDistance + YSize) { //Comment the X and Y Axes Coordinates and Mouse is on the dashboard Comment("X: ", lparam, "\nY: ", dparam, "\nMouse is on the Dashboard"); } else { //Comment the X and Y Axes Coordinates and Mouse is not on the dashboard Comment("X: ", lparam, "\nY: ", dparam, "\nMouse is NOT on the Dashboard"); } } }
Defined the variables X, Y, name, XDistance, YDistance, XSize, YSize. Got the X from lparam, Y from dparam, name is just the string name we set above, XDistance, YDistance, XSize, YSize using ObjectGetInteger() function.
Remember our goal here is to just make the dashboard move smoothly then we worry about other things.
Result:
Figure 4. Mouse is on the Dashboard
As you can see whenever mouse is on the dashboard, comment changes. So our logic is working and now we know if the mouse is on the dashboard or not.
Now we will be needing the mouse buttons state, Remember the theory if Mouse Left was clicked then sparam was 1, Let's use that
void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam) { //Verify the event that triggered the OnChartEvent was CHARTEVENT_MOUSE_MOVE because we only want to execute out code when that is the case if(id == CHARTEVENT_MOUSE_MOVE) { //define X, Y, XDistance, YDistance, XSize, YSize int X = (int)lparam; int Y = (int)dparam; int MouseState = (int)sparam; string name = "TestRectangle"; int XDistance = ObjectGetInteger(0, name, OBJPROP_XDISTANCE); //Should be 100 initially as we set it in OnInit() int YDistance = ObjectGetInteger(0, name, OBJPROP_YDISTANCE); //Should be 100 initially as we set it in OnInit() int XSize = ObjectGetInteger(0, name, OBJPROP_XSIZE); //Should be 200 initially as we set it in OnInit() int YSize = ObjectGetInteger(0, name, OBJPROP_YSIZE); //Should be 200 initially as we set it in OnInit() //Check Dashboard move conditions if(X >= XDistance && X <= XDistance + XSize && Y >= YDistance && Y <= YDistance + YSize && MouseState == 1) { //Comment that the dashboard is ready to move Comment("Dashboard is ready to move."); } else { //Comment that the dashboard is not ready to move Comment("Dashboard is NOT ready to move."); } } }
I have added
int MouseState = (int)sparam; //To get the mouse state: 1 -> Mouse Left Button Down (You can check the other above)
in the variables and added the condition that
if(MouseState == 1) // This insures that Mouse Left button in pressed
in the if statement and changed the comments a little bit
Now Whenever mouse Left button is in pressed state on the dashboard we get a comment "Dashboard is ready to move." otherwise "Dashboard is NOT ready to move."
Let's see it in action:
Figure 5. Dashboard is ready to move
See the comment change when Mouse Left button is held down
Now with that being done, We are ready to move our dashboard, So now How do we go about doing it? Let's try to find out.
We know that dashboard will be moving with our mouse and How do we change dashboard position? Ofcourse wIth XDistance and YDistance property. So We change XDistance and YDistance but by how much? because dashboard is moving with mouse, the dashboard should move same as mouse right?
Well Then by how much did our mouse move by? That we will have to figure out but again How? That was a lot of questions just now, let's make a plan out of those questions
Plan:
- Find out by how much our mouse moved after we pressed MLB (Mouse Left button)
- Move the dashboard by exactly the same amount as mouse is moved by
- Do this untill MLB is pressed down, Stop moving the dashboard after that
Let's go one step at a time,
We can always get the current mouse position right so what if we save the mouse position when MLB was clicked the first time?
and we can know if the MLB is pressed from MouseState variable we created that stores sparam
Below is the code that dectects the MLB click first time:
int previousMouseState = 0; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam) { //Verify the event that triggered the OnChartEvent was CHARTEVENT_MOUSE_MOVE because we only want to execute out code when that is the case if(id == CHARTEVENT_MOUSE_MOVE) { int MouseState = (int)sparam; bool mblDownFirstTime = false; if(previousMouseState == 0 && MouseState == 1) { mblDownFirstTime = true; } previousMouseState = MouseState; } } //+------------------------------------------------------------------+
I have removed other things to make it easier to see and understand. This method is quite commonly used in create Trailing functions fro EA or detecting new bar etc.
Let's break it down:
-
int previousMouseState = 0;
We declare a int variable named previousMouseState on global space and set it to 0, this variable will store the MouseState value from the last time CHARTEVENT_MOUSE_MOVE event happened, Well How? Have some patience you will know soon enough.
-
int previousMouseState = 0;
We declare a int variable named previousMouseState on global space and set it to 0, this variable will store the MouseState value from the last time CHARTEVENT_MOUSE_MOVE event happened, Well How? Have some patience you will know soon enough.
-
int MouseState = (int)sparam; bool mblDownFirstTime = false; if(previousMouseState == 0 && MouseState == 1) { mblDownFirstTime = true; }
First We declare one MouseState and set it equal to sparam which contains the Mouse State, two we declare a bool variable named mblDownFirstTime and set it's default value to falseThen we check for 2 conditions, one previousMouseState should be 0 (MLB Up, No mouse button pressed) and (&&) MouseState should be 1 (MLB Down)
This condition basically confirms or denies that MLB is down the first time or not, once we know it's the first time, We set mblDownFirstTime equal to true so that we can use this variable later.
Now With that, Our first step is completed, let move to Step 2 and 3.
Now, There are many ways we can proceed further but to get a very smooth and subtle movement, Below are the step we will be taking:
- Create a bool global variable named movingState that we will set true once user clicks MLB on the the dashboard, also declare MLB Down X, MLB Down Y, MLB Down XDistance, MLB Down YDistance (here, MLB Down means the first the MLB was down) Those will be needed to modify the dashboards position
- While movingState is true, We will be updating dashboard position according to change in mouse position from the mouse initial Position (when MLB was first clicked)
- While movingState is true, We will be updating dashboard position according to change in mouse position from the mouse initial Position (when MLB was first clicked)
New Code:
int previousMouseState = 0; int mlbDownX = 0; int mlbDownY = 0; int mlbDownXDistance = 0; int mlbDownYDistance = 0; bool movingState = false; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam) { //Verify the event that triggered the OnChartEvent was CHARTEVENT_MOUSE_MOVE because we only want to execute out code when that is the case if(id == CHARTEVENT_MOUSE_MOVE) { if(previousMouseState == 0 && MouseState == 1) { mlbDownX = X; mlbDownY = Y; mlbDownXDistance = XDistance; mlbDownYDistance = YDistance; if(X >= XDistance && X <= XDistance + XSize && Y >= YDistance && Y <= YDistance + YSize) { movingState = true; } } if(movingState) { ChartSetInteger(0, CHART_MOUSE_SCROLL, false); ObjectSetInteger(0, name, OBJPROP_XDISTANCE, mlbDownXDistance + X - mlbDownX); ObjectSetInteger(0, name, OBJPROP_YDISTANCE, mlbDownYDistance + Y - mlbDownY); ChartRedraw(0); } if(MouseState == 0) { movingState = false; ChartSetInteger(0, CHART_MOUSE_SCROLL, true); } previousMouseState = MouseState; } } //+------------------------------------------------------------------+
Let's break it down in simpler terms:
-
int mlbDownX = 0; int mlbDownY = 0; int mlbDownXDistance = 0; int mlbDownYDistance = 0; bool movingState = false;
We created a few variables in Global Space, we have already talked about the previousMouseState other than that:
- mlbDownX -> To hold X Coordinate when MLB was down the first time
- mlbDownY -> To hold Y Coordinate when MLB was down the first time
- mlbDownXDistance -> To hold XDistance property of the dashboard when the MLB was pressed first time
- mlbDownYDistance -> To hold YDistance property of the dashboard when the MLB was pressed first time
- movingState -> To hold true if we are moving the dashboard else false
if(previousMouseState == 0 && MouseState == 1) { mlbDownX = X; mlbDownY = Y; mlbDownXDistance = XDistance; mlbDownYDistance = YDistance; if(X >= XDistance && X <= XDistance + XSize && Y >= YDistance && Y <= YDistance + YSize) { movingState = true; } }
First we check if it is the first MLB click, if it is then we update mlbDownX, mlbDownY, mlbDownXDistance, mlbDownYDistance to the current X, Y, XDistance, YDistance respectively, we will be using them later.Then we check if MLB was down on the dashboard and if it was down on the dashboard then we set movingState to true.
-
if(movingState) { ChartSetInteger(0, CHART_MOUSE_SCROLL, false); ObjectSetInteger(0, name, OBJPROP_XDISTANCE, mlbDownXDistance + X - mlbDownX); ObjectSetInteger(0, name, OBJPROP_YDISTANCE, mlbDownYDistance + Y - mlbDownY); ChartRedraw(0); }
And if movingState is true then we modify the XDistance and YDistance,
X - mlbDownX // Change in Mouse X Position form the initial click and Y - mlbDownY // Change in Mouse X Position form the initial click
These above are the change in Mouse Position from the initial click and we add them to mlbDownXDistance and mlbDownYDistance to get the new dashboard position, make sense if you think about it.
And We also set CHART_MOUSE_SCROLL chart property to false so that chart doesn't move with our dashboard then we ofcourse redraw the chart to get a very smooth subtle movement.
-
if(MouseState == 0) { movingState = false; ChartSetInteger(0, CHART_MOUSE_SCROLL, true); }
Now once we leave the MLB i.e. MouseState becomes 0
Then we set movingState to false and again allow the chart to be moved by setting CHART_MOUSE_SCROLL to true again.
Now, With that being done, Our Code is completed, Give your a pat on the back if you the followed till now because we are almost done for the Part I.
Our Complete Code:
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //Set the name of the rectangle as "TestRectangle" string name = "TestRectangle"; //Create a Rectangle Label Object at (time1, price1)=(0,0) ObjectCreate(0, name, OBJ_RECTANGLE_LABEL, 0, 0, 0); //Set XDistance to 100px i.e. Distance of Rectangle Label 100px from Left of the Chart Window ObjectSetInteger(0, name, OBJPROP_XDISTANCE, 100); //Set YDistance to 100px i.e. Distance of Rectangle Label 100px from Top of the Chart Window ObjectSetInteger(0, name, OBJPROP_YDISTANCE, 100); //Set XSize to 200px i.e. Width of Rectangle Label ObjectSetInteger(0, name, OBJPROP_XSIZE, 200); //Set YSize to 200px i.e. Height of Rectangle Label ObjectSetInteger(0, name, OBJPROP_YSIZE, 200); //Set Chart property CHART_EVENT_MOUSE_DOWN to true ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //Declare some global variable that will be used in the OnChartEvent() function int previousMouseState = 0; int mlbDownX = 0; int mlbDownY = 0; int mlbDownXDistance = 0; int mlbDownYDistance = 0; bool movingState = false; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam) { //Verify the event that triggered the OnChartEvent was CHARTEVENT_MOUSE_MOVE because we only want to execute out code when that is the case if(id == CHARTEVENT_MOUSE_MOVE) { //define X, Y, XDistance, YDistance, XSize, YSize int X = (int)lparam; int Y = (int)dparam; int MouseState = (int)sparam; string name = "TestRectangle"; int XDistance = (int)ObjectGetInteger(0, name, OBJPROP_XDISTANCE); //Should be 100 initially as we set it in OnInit() int YDistance = (int)ObjectGetInteger(0, name, OBJPROP_YDISTANCE); //Should be 100 initially as we set it in OnInit() int XSize = (int)ObjectGetInteger(0, name, OBJPROP_XSIZE); //Should be 200 initially as we set it in OnInit() int YSize = (int)ObjectGetInteger(0, name, OBJPROP_YSIZE); //Should be 200 initially as we set it in OnInit() if(previousMouseState == 0 && MouseState == 1) //Check if this was the MLB first click { mlbDownX = X; //Set mlbDownX (Variable that stores the initial MLB X location) equal to the current X mlbDownY = Y; //Set mlbDownY (Variable that stores the initial MLB Y location) equal to the current Y mlbDownXDistance = XDistance; //Set mlbDownXDistance (Variable that stores the initial XDistance i.e. Width of the dashboard) equal to the current XDistance mlbDownYDistance = YDistance; //Set mlbDownYDistance (Variable that stores the initial YDistance i.e. Height of the dashboard) equal to the current YDistance if(X >= XDistance && X <= XDistance + XSize && Y >= YDistance && Y <= YDistance + YSize) //Check if the click was on the dashboard { movingState = true; //If yes the set movingState to True } } if(movingState)//if movingState is true, Update the Dashboard position { ChartSetInteger(0, CHART_MOUSE_SCROLL, false);//Restrict Chart to be moved by Mouse ObjectSetInteger(0, name, OBJPROP_XDISTANCE, mlbDownXDistance + X - mlbDownX);//Update XDistance to: mlbDownXDistance + (X - mlbDownX) ObjectSetInteger(0, name, OBJPROP_YDISTANCE, mlbDownYDistance + Y - mlbDownY);//Update YDistance to: mlbDownYDistance + (Y - mlbDownY) ChartRedraw(0); //Redraw Chart } if(MouseState == 0)//Check if MLB is not pressed { movingState = false;//set movingState again to false ChartSetInteger(0, CHART_MOUSE_SCROLL, true);//allow the cahrt to be moved again } previousMouseState = MouseState;//update the previousMouseState at the end so that we can use it next time and copare it with new value } } //+------------------------------------------------------------------+
Now That simple code does the job
Result:
Figure 6. Final Result
Now with that we will wrap this section now
Conclusion
I am really sorry to leave to on a kind of a cliffhanger because we have not created something very unique yet. But be assured another part will be coming in a few days in which:
- We will advance to creating multiple GUI on a single chart efficiently (not just by copy pasting stuff)
- we'll delve into enhancing our GUI by adding and customizing various elements, tailoring it to your unique needs. We've also catered to those eager to dive right in with a streamlined guide offering quick steps to make your GUI movable.
By the end of this journey, you'll have gained a valuable skill in creating and manipulating movable GUI in MQL5, a powerful tool for any trader. So, let's get started on this exciting journey!
Hope you liked it and it helped you in any slightest way. Hope to see you again in the next part.
Happy Coding
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I am glad to hear that it helped you.
Second part will be published today, You will find how to move multiple rectangle labels on the same chart in it.
Great article! I'm looking forward to the next one but have not seen it. I'm hoping the next article will demonstrate placing objects e.g. text buttons panels etc on the dashboard. Ot would also be very helpful to have the dashboard enameled so that other instances of it could be placed on the "mother" as children.
I am glad you liked my article. I hope you like second part too but no, adding text buttons to panels is not covered in second part, it's covered in 3rd part. 3rd Part will be published in a few days.
Millions thanks, this helps me a lot!
You’re very welcome
I am glad that I was able to help you with my article.