Discussing the article: "Improve Your Trading Charts With Interactive GUI's in MQL5 (Part III): Simple Movable Trading GUI" - page 2

 
Maxim Kuznetsov #:

there is a darkness of elaborate methods with beautiful arrows "how to implement UI to avoid excruciating pain" :-) MVC and similar. So there the front end (win,gtk,qt,web) can sometimes be changed with a slight movement of the hand.

None of them has been implemented in MQL. Everything is nailed down, worse than TurboVision - even though it has classes from Adam, but it has models

Individuals have been writing for years(!!!) about "easy and simple" and "simple interface", but it is exactly the same as in this article. A lot of code that does not make anything easier. The only effect is a bonus on the author's account.

Oh, the mere mention of MVC makes me cringe.

It has remained since the time when I made my wife's site, an online shop on the OcStore engine.

By the time came at least some understanding of how it works, I was half grey))))


Let's not judge strictly, this series of articles is aimed at beginners.

The articles are written clearly and lucidly, and to write clearly is not such an easy task.

The author, copes with this task perfectly.

 
Aleksandr Slavskii #:

Ouch, the mere mention of MVC makes me cringe.

It's been there since I made my wife's website on the OcStore engine.

By the time I came to understand how it works, I was half grey))))


Let's not judge strictly, this series of articles is aimed at beginners.

The articles are written clearly and understandably, and writing clearly is not such an easy task.

The author, copes with this task perfectly.

I have a memory of counting the width/height and relative and absolute coordinates of a shitty button is depressing :-)

2024 - but still the library user has to count pixels.

the given dialogue, in the form of a volume input field and two buy/sell buttons.

how does the above dialogue solve problems with volume tolerance and tradeability? yes, lots cannot be less than minimum, incremented by steps and not more than maximum. Buy/Sell is not always possible.
Any hints on solutions ? No.

HOW ? in hand-to-hand...inside the EA manually manage all the options of a particular GUI. It's no better than using terminal functions directly.

between ObjectSetXXX(chart,objName,propertyName,propertyValue) and obj.SetInteger(value) - the difference is covered by defines, no OOP is needed here.

---

it's not about the article, it's about "writers" in general. You'd better read

 
Maxim Kuznetsov # :

I have a memory of calculating the width/height and the relative and absolute coordinates of a button, which is depressing :-)

2024 - but still, the library user must count pixels

the given dialogue, in the form: volume input field and two buy/sell buttons

How does the above dialogue solve problems with the admissibility of volumes and the possibility of trading? Yes, lots cannot be less than the minimum, they are incremented in steps and no more than the maximum. Buy/Sell is not always possible. Are there any hints of solutions? There is not

HOW? In hand-to-hand combat... inside the advisor, manually control all the options of a specific GUI. It's no better than using the terminal functions directly.

between ObjectSetXXX(chart,objName,propertyName,propertyValue) and obj.SetInteger(value) - the difference is covered by definitions, no OOP is needed here

---

This is no longer in terms of the article, it's generally about "writers". It would be better if they read

Just one thing, I would like to point out is, this series was not written for this Buy/Sell GUI rather it was written for any GUI and this Buy/Sell GUI acts as a simple example.

Thanks for giving the series such thoughts, would appreciate suggestions.

Regards

 
Maxim Kuznetsov #:

I have a memory of counting the width/height and relative and absolute coordinates of a shitty button makes me despondent :-)

2024 - but still a library user has to count pixels

the given dialogue, in the form of: volume input field and two buy/sell buttons

how does the above dialogue solve the problems with volume tolerance and tradeability? yes, lots cannot be less than minimum, incremented by steps and not more than maximum. Buy/Sell is not always possible.
Any hints of solutions ? No.

HOW ? in hand-to-hand...inside the EA manually manage all the options of a particular GUI. It is no better than using terminal functions directly.

between ObjectSetXXX(chart,objName,propertyName,propertyValue) and obj.SetInteger(value) - the difference is covered by defines, no OOP is needed here.

---

it's not about the article, it's about "writers" in general. You'd better read

Man, this is only my third panel, I don't want to remember the first two, if any coder sees them, I'll be ashamed.

I would like to do it now so that next time I don't have to mess with it so much.

Now in the plugin file left only a class with code for dragging all the elements of the panel and a bunch of gets.

class CreateObject
  {
private:
   string            _name; // Name of the rectangle label
   int               previousMouseState, mlbDownX, mlbDownY, mlbDownXDistance, mlbDownYDistance; // Mouse state tracking variables
   bool              movingState; // State for whether the object is moving
   string            addedNames[]; // Array of added names
   long              addedXDisDiffrence[], addedYDisDiffrence[]; // Arrays to store added distance differences
   void              Destroy() {for(int i = 0; i < (int)addedNames.Size(); i++)ObjectDelete(0, addedNames[i]); ObjectDelete(0, _name);} // Destroy method for rectangle label
public:
                     CreateObject(void); // Constructor
                    ~CreateObject(void); // Destructor
   void              SetName(string name) {_name = name;}
   string            GetText(string name) {return ObjectGetString(0, name, OBJPROP_TEXT);} // Method to retrieve the text content
   long              GetType(string name) {return ObjectGetInteger(0, name, OBJPROP_TYPE);}
   double            GetPrice(string name) {return ObjectGetDouble(0, name, OBJPROP_PRICE);}
   void              OnEvent(int id, long lparam, double dparam, string sparam); // Event handler method
   void              Add(string name); // Method to add a name to the object
  };
//+------------------------------------------------------------------+
CreateObject::CreateObject(void) {}
//+------------------------------------------------------------------+
CreateObject::~CreateObject(void) {Destroy();}
//+------------------------------------------------------------------+
//| Event handling for mouse movements |
//+------------------------------------------------------------------+
void CreateObject::OnEvent(int id, long lparam, double dparam, string sparam)
  {
// Handle mouse movement events for dragging the rectangle label
   if(id == CHARTEVENT_MOUSE_MOVE && lparam > 20 && dparam > 20 &&
      lparam < ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) - 20 && dparam < ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS) - 20)
     {
      int X = (int)lparam;
      int Y = (int)dparam;
      int MouseState = (int)sparam;

      string name = _name;
      int XDistance = (int)ObjectGetInteger(0, name, OBJPROP_XDISTANCE);
      int YDistance = (int)ObjectGetInteger(0, name, OBJPROP_YDISTANCE);
      int XSize = (int)ObjectGetInteger(0, name, OBJPROP_XSIZE);
      int YSize = (int)ObjectGetInteger(0, name, OBJPROP_YSIZE);

      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);
         for(int i = 0; i < ArraySize(addedNames); i++)
           {
            ObjectSetInteger(0, addedNames[i], OBJPROP_XDISTANCE, mlbDownXDistance + X - mlbDownX - addedXDisDiffrence[i]);
            ObjectSetInteger(0, addedNames[i], OBJPROP_YDISTANCE, mlbDownYDistance + Y - mlbDownY - addedYDisDiffrence[i]);
           }
         ChartRedraw(0);
        }

      if(MouseState == 0)
        {
         movingState = false;
         ChartSetInteger(0, CHART_MOUSE_SCROLL, true);
        }

      previousMouseState = MouseState;
     }
  }
//+------------------------------------------------------------------+
//| Method to add an object by name to the rectangle label |
//+------------------------------------------------------------------+
void CreateObject::Add(string name)
  {
// Add a new object by name to the rectangle label and track distances
   ArrayResize(addedNames, ArraySize(addedNames) + 1);
   ArrayResize(addedXDisDiffrence, ArraySize(addedXDisDiffrence) + 1);
   ArrayResize(addedYDisDiffrence, ArraySize(addedYDisDiffrence) + 1);

   addedNames[ArraySize(addedNames) - 1] = name;
   addedXDisDiffrence[ArraySize(addedXDisDiffrence) - 1] = ObjectGetInteger(0, _name, OBJPROP_XDISTANCE) - ObjectGetInteger(0, name, OBJPROP_XDISTANCE);
   addedYDisDiffrence[ArraySize(addedYDisDiffrence) - 1] = ObjectGetInteger(0, _name, OBJPROP_YDISTANCE) - ObjectGetInteger(0, name, OBJPROP_YDISTANCE);
  }
//+------------------------------------------------------------------+

And below I just have functions for drawing objects, copied from the help, it seems so convenient to have everything in one pile.

As a result, the code in the Expert Advisor was long, now it is wide, in general, I changed from one thing to another.

Another plug-in file with frequently used trading functions, such as count all positions, normalise price, close positions, etc.

But it's still a bit cumbersome and not universal.

In the next panel we will have to calculate each field and write processing for these fields (buttons/entry field).

And I can't think of a scheme how to do it all more universally.

Can you give me some good hints on how to design the code?

 
Aleksandr Slavskii #:

But it's still kind of cumbersome and not versatile.

In the next panel we will have to calculate each field and write processing for these fields (buttons/entry field).

And I can't think of any way to make it more universal.

Can you give me some good hints on how to design the code?

The most practical and universal variant is to design forms visually, without caring about the layout code at all - this is what classes should do. One of the possible solutions was in the article.

Язык MQL как средство разметки графического интерфейса MQL-программ (Часть 3). Дизайнер форм
Язык MQL как средство разметки графического интерфейса MQL-программ (Часть 3). Дизайнер форм
  • www.mql5.com
В этой статье мы завершаем описание концепции построения оконного интерфейса MQL-программ с помощью конструкций языка MQL. Специальный графический редактор позволит интерактивно настраивать раскладку, состоящую из основных классов элементов GUI, и затем экспортировать её в MQL-описание для использования в вашем MQL-проекте. Представлено внутреннее устройство редактора и руководство пользователя. Исходные коды прилагаются.
 
Stanislav Korotky #:

The most practical and universal option is to design forms visually, without worrying about the layout code at all - that's exactly what classes should do. One of the possible solutions was in the article.

I remembered :-)

for those who are not for the market, want more or less complex but beautiful, and it is too lazy to write DLL, there is GtkServer https://sourceforge.net/projects/gtk-server/ and Glade form designer to it.

Methodology: GtkServer is launched as a tcp listener, advisor using SocketOpen/SocketSend sends text "load form" (or itself by steps forms gtk widgets) and also reads the result....

GTK-server
  • 2018.11.27
  • sourceforge.net
From AI to Wasm, eBPF, and environmental sustainability, KubeCon + CloudNative Con Europe is the place to experience everything cloud native has to offer and also take a deep dive into new and promising...
 
Stanislav Korotky #:

The most practical and universal option is to design forms visually, without worrying about the layout code at all - that's exactly what classes should do. One of the possible solutions was in the article.

Stanislav, well, under the article for beginners you provide a link to the article for advanced users :)

I read it, not read it, but just read it, because my level in programming is much lower than I need to understand what is written there.

I try to use what I don't understand as little as possible. A recent situation has rooted me in this even more strongly.

You are probably reading the topic "Errors, bugs, questions", so I had a task to display arrows from closed positions on a renko-graph, entry-exit between them - a line.

I decided not to write it myself, but to take a ready-made code from Saiber, as a result - half a day of wasted time. Saiber corrected its code in the end, but I lost time.

And if I wanted to take the code from your article and needed to tweak something, well, you understand, nothing good would come out of it.

I have a simpler task than you set for yourself when writing your article. I just need to make it so that I can build the next panel from pieces of ready-made code like children build houses from lego.

I don't need OOP for this purpose at all, in my opinion. I don't know it, so I don't like it.

The MVC principle is quite suitable for my purposes, if I understood it correctly)))))

In general, I already have a picture of how it should be.


By the way, can you tell me how to make it so that when I access the functions of the inheritor class from the programme, I don't see the functions of the base class? Well, if it is possible.

 
Maxim Kuznetsov #:

it came to mind :-)

for those who are not for the market, want more or less complex but beautiful, and it is too lazy to write a DLL, there is GtkServer https://sourceforge.net/projects/gtk-server/ and Glade form designer to it.

Methodology: GtkServer is launched as a tcp listener, advisor using SocketOpen/SocketSend sends text "load form" (or itself by steps forms gtk widgets) and also reads the result....

You too :)

I generallyperceive words like tcp listener, SocketOpen/SocketSend as profanity , Idon't even know their meaning without google, and you suggest to use it.

Gentlemen, have a conscience, stop scaring people with your terminology)))))

 
Aleksandr Slavskii #:

Stanislav, well yo-ma-yo, under the article for beginners you throw a link to the article for advanced :)

I have read it, not read it, but just read it, because my level in programming is much lower than I need to understand what is written there.

I try to use what I don't understand as little as possible. A recent situation has rooted me in this even more strongly.

Unfortunately, the situation with software is such that it is impossible to understand everything yourself. According to this logic, the operating system should be customised (which is what some Linux apologists do).

That's why the modern approach is to take ready-made bricks (which do more or less what you need) and dock them (without going deep into implementation).

I was merely answering the question of how to do more universally. You can't argue with the fact that my article is complicated, but the point is that you can describe the necessary GUI as a template without programming, just by plugging in enclosures to get controllers, window dragging, resizing and so on.

 
Excellent, very good, I can tinker with what I can't code, but there are some features I can't handle, is it easy to help me modify? Add an input box with a +- sign. Thank you!