Gallery of UIs written in MQL - page 54

 

I also have a full screen canvas redrawing completely at each change, but it takes no longer than 50 ms....

The most expensive is to draw text. Therefore, in order not to use TextOut every time, I store them in arrays. It turns out much faster.

 

The main challenge now is to give the user programmatic control over the interface controls.

Technically, the task is not difficult, because in the symbiotic union of the user program and the engine, the graphical core is visible at a global level to the algorithms of both parties. The problem is that the user does not know how to work with the kernel. He does not know and does not understand the principles of element management. Therefore, it is necessary to give familiar wrappers - functions through which he can access the kernel and change values.

But there is a nuance. The names of functions are too long. After all, each functional wrapper of an interactive element should include the names of the element and the window. This is necessary for orientation among the names. Otherwise, the user will easily get confused and will not understand their function-wrappers. Also, the names may coincide, and this is not good at all. So it turns out - you need to generate names from two components: the name of the element and the name of the window. Then there is no confusion, but the names of wrappers become too long. Especially with the side of passed parameters. In addition, you need to add prefixes to functions to find them quickly via intellisense. This allows efficient filtering of the pop-up sample. Handy. BUT LONG!

Not only that. The problem is the parameters being passed. The choice is either to write wrappers for every preset get/set-properties of elements and windows, or each wrapper accepts the full list of parameters from a user call. This is terribly inconvenient. And most importantly, it's hard to explain.


There is a way out and it is simple. And here is what it is: a group of abstract properties. Global variables simultaneously visible from the side of the user's programme and the engine.

How it will work:

1. All wrappers of elements and windows will address the central function and pass their indices. It will use them to determine the target element/window of the call.

2. After this call, the user will set the selected set of abstract properties to the required values.

3. Call the central function and pass the c.word "Set".

4. Central will set the values of the abstract properties from their global variables to the target properties of the particular element or window.

5. It will update the element/window and reset the abstract properties to zero.

That's it.

In my opinion, a simple and efficient solution that will provide:

a) Easy access to properties of any elements and windows, without passing parameters to a function that requires strict consistency. (Plus - limitation on the number of passed parameters. And the call turns out to be long and unreadable).

c) Free combination of a set of properties of elements and windows when setting/receiving values anywhere in the programme.


If anyone sees disadvantages - speak up. It would be nice to coordinate this issue before release.

 
Nikolai Semko CCanvas class (if you use it) and print this counter, for example when count%100 == 0.

Nicholas, it is worth considering that we are talking about multiple GUI windows. In the last release there were 17 of them. Each one has hundreds of elements. And each element is complex. It consists of a set of parts. Each detail is a section of the canvas that you need to pass through and in the right place to fill with the necessary values.

If we take the average number of windows 10 (Papkov, I remember, ordered an interface of 11 windows), and imagine that each has a set of elements or a table, then it becomes clear why the complete rendering of the entire interface takes so much time. Let me remind you that in the interface there are icons, shadows, surface gradient, various frames.... then in total the complete drawing of ALL the interface will take at least 500 ms. There's nothing you can do about it.

It can be faster if you reduce the number of windows or simplify the graphics.

About redrawing - I have almost no pure ChartRedraw() calls. The _ChartRedraw flag is used everywhere. When this flag is set, the ChartRedraw() function is called at the next timer iteration, after 25 ms. That is - once. This way I avoid unnecessary redraws. Only in rare cases I make a direct call to ChartRedraw().

 
Andrey Barinov #:

I also have the full screen canvas redrawing completely every time I change, but it takes no longer than 50 ms...

The most expensive is to draw text. Therefore, in order not to use TextOut every time, I store them in arrays. It turns out much faster.

Well, simple arithmetic works here: the sum of areas of 10 - 17 windows is much larger than the full screen. Agreed. Plus secondary additional drawing necessary to create shadows, icons, frames....

And about TextOut I will check and write. Interesting idea.

 

Conducted a test:

Went into the Demo project 1.mqh file and set all windows to OOI flag. (opening on initialisation).

In total - 15 windows of different sizes and different contents. 2 windows with scroll bars and tables (so their canvas is partially hidden and actually 2-3 times longer. The full length can be judged by the ratio of slider to scroll bar). Total drawing area(minimum) 2000*1000 pixels. But I think it's more than that. Total drawn 1158 parts (checked after printing the core). Time of full drawing of all canvases from zero from 1600 - to 1900 ms.

Again pay attention to the amount of details that had to be drawn. Shadows, icons, gradients, frames, texts.


The drawing time is on the screenshot:


 
There may be a way to speed up the drawing. Remove the bottom base of the window platforms. These are big canvases behind the front side where elements are located. If you remove them, it will be 2 times faster. I'll have to think about it.
 
Is it possible to draw certain windows only when they are open? It's rare to have a dozen windows open at once. There is no need to do so.
 
hini #:
Can I draw certain windows only when they are open? It is rare to have dozens of windows open at the same time. There's no need for that.

That's the only thing that happens, believe me. I'm only talking about the first drawing of all the interface windows at once. The first drawing takes the most time. And after that, all images are already saved and retrieved from memory if necessary. With one call they are attached to their canvases in a few milliseconds. This is not a problem. You just want to compress the time of the first drawing.

 
Реter Konow #:
There may be a way to speed up the drawing. Remove the bottom base of the window platforms. These are large canvases behind the front side where elements are located. If you remove them, it will be 2 times faster. I'll have to think about that.

This is the canvas I'm talking about:

1. The front side where the elements are located:


2. The back side where the window's buttons (cross, minimiser), icon and name text are located. However, the entire window is coloured green and time has been spent on it. But, the user sees only the frames and the window header. It turns out that in this place the drawing is done in vain:


 
I think if you don't draw the invisible part of the back side, you can speed up the first drawing of the window by at least a third. I can' t say for sure yet, you need to check. Let it draw only the frame and the hat. Skip the rest. In any case there will be a gain.