Galería de interfaces de usuario escritas en MQL - página 54

 
Algo va mal, Peter.
Un retraso de un segundo es un retraso prohibitivo. La formación de la interfaz más complicada para toda la ventana no debería superar los 50 milisegundos.
Realmente parece que la lógica de renderizado está sobrecargada con las funciones Update (en realidad ChartRedraw).
Para comprobar esta suposición, pon un contador estático en la función Update de la clase CCanvas (si la utilizas) e imprime este contador, por ejemplo cuando count%100 == 0.
 

También tengo un lienzo a pantalla completa redibujándose completamente en cada cambio, pero no tarda más de 50 ms....

Lo más costoso es dibujar texto. Por eso, para no usar TextOut cada vez, los almaceno en arrays. Resulta mucho más rápido.

 

El principal reto ahora es dar al usuario el control programático sobre los controles de la interfaz.

Técnicamente, la tarea no es difícil, porque en la unión simbiótica del programa de usuario y el motor, el núcleo gráfico es visible a nivel global para los algoritmos de ambas partes. El problema es que el usuario no sabe cómo trabajar con el núcleo. No conoce ni entiende los principios de la gestión de elementos. Por lo tanto, es necesario dar envolturas familiares - funciones a través del cual se puede acceder al núcleo y cambiar los valores.

Pero hay un matiz. Los nombres de las funciones son demasiado largos. Después de todo, cada envoltura funcional de un elemento interactivo debe incluir los nombres del elemento y de la ventana. Esto es necesario para orientarse entre los nombres. De lo contrario, el usuario se confundirá fácilmente y no entenderá sus envolturas funcionales. Además, los nombres pueden coincidir, y esto no es nada bueno. Así que resulta - que necesita para generar nombres de dos componentes: el nombre del elemento y el nombre de la ventana. Entonces no hay confusión, pero los nombres de las envolturas se vuelven demasiado largos. Especialmente con el lado de los parámetros pasados. Además, es necesario añadir prefijos a las funciones para encontrarlas rápidamente a través de intellisense. Esto permite un filtrado eficiente de la muestra emergente. Práctico. ¡PERO LARGO!

Y no sólo eso. El problema son los parámetros que se pasan. La opción es o bien escribir wrappers para cada preset get/set-properties de elementos y ventanas, o bien cada wrapper acepta la lista completa de parámetros de una llamada de usuario. Esto es terriblemente inconveniente. Y lo más importante, es difícil de explicar.


Hay una salida y es sencilla. Y esto es lo que es: un grupo de propiedades abstractas. Variables globales visibles simultáneamente desde el lado del programa del usuario y del motor.

Cómo funcionará:

1. Todas las envolturas de elementos y ventanas se dirigirán a la función central y le pasarán sus índices. Ésta los utilizará para determinar el elemento/ventana de destino de la llamada.

2. Después de esta llamada, el usuario establecerá el conjunto seleccionado de propiedades abstractas a los valores requeridos.

3. Llame a la función central y pase la palabra c "Set".

4. Central establecerá los valores de las propiedades abstractas desde sus variables globales a las propiedades de destino del elemento o ventana en particular.

5. Actualizará el elemento/ventana y pondrá a cero las propiedades abstractas.

Y ya está.

En mi opinión, una solución simple y eficiente que proporcionará:

a) Fácil acceso a las propiedades de cualquier elemento y ventana, sin pasar parámetros a una función que requiere una coherencia estricta. (Plus - limitación en el número de parámetros pasados. Y la llamada resulta larga e ilegible).

c) Combinación libre de un conjunto de propiedades de elementos y ventanas al establecer/recibir valores en cualquier parte del programa.


Si alguien ve desventajas, que hable. Estaría bien coordinar este tema antes del lanzamiento.

 
Nikolai Semko clase CCanvas (si la usas) e imprime este contador, por ejemplo cuando count%100 == 0.

Nicholas, vale la pena considerar que estamos hablando de múltiples ventanas GUI. En la última versión había 17. Cada una tiene cientos de elementos. Y cada elemento es complejo. Consiste en un conjunto de partes. Cada detalle es una sección del lienzo por la que hay que pasar y en el lugar adecuado rellenar con los valores necesarios.

Si tomamos el número medio de ventanas 10 (Papkov, recuerdo, encargó una interfaz de 11 ventanas), e imaginamos que cada una tiene un conjunto de elementos o una tabla, entonces queda claro por qué la renderización completa de toda la interfaz lleva tanto tiempo. Permítanme recordarles que en la interfaz hay iconos, sombras, gradiente de superficie, varios marcos.... entonces en total el dibujo completo de TODA la interfaz tardará al menos 500 ms. No hay nada que puedas hacer al respecto.

Puede ser más rápido si reduces el número de ventanas o simplificas los gráficos.

Sobre el redibujado - Casi no tengo llamadas puras a ChartRedraw(). La bandera _ChartRedraw se utiliza en todas partes. Cuando esta bandera está activada, la función ChartRedraw() es llamada en la siguiente iteración del temporizador, después de 25 ms. Esto es - una vez. Es decir - una vez. De esta forma evito redibujos innecesarios. Sólo en raros casos hago una llamada directa a ChartRedraw( ).

 
Andrey Barinov #:

También tengo el lienzo a pantalla completa redibujándose completamente cada vez que cambio, pero no tarda más de 50 ms...

Lo más costoso es dibujar texto. Por eso, para no usar TextOut cada vez, los almaceno en arrays. Resulta mucho más rápido.

Bueno, la simple aritmética funciona aquí: la suma de las áreas de 10 - 17 ventanas es mucho mayor que la pantalla completa. De acuerdo. Además de dibujo adicional secundaria necesaria para crear sombras, iconos, marcos....

Y sobre TextOut voy a comprobar y escribir. Interesante idea.

 

Realicé una prueba:

Fui al archivo Demo project 1.mqh y puse todas las ventanas en bandera OOI. (apertura en la inicialización).

En total - 15 ventanas de diferentes tamaños y diferentes contenidos. 2 ventanas con barras de desplazamiento y tablas (por lo que su lienzo está parcialmente oculto y en realidad 2-3 veces más largo. La longitud total se puede juzgar por la relación entre el deslizador y la barra de desplazamiento). Área total de dibujo(mínimo) 2000*1000 píxeles. Pero creo que es más que eso. Total dibujado 1158 partes (comprobado después de imprimir el núcleo). Tiempo de dibujo completo de todos los lienzos de cero de 1600 - a 1900 ms.

Una vez más prestar atención a la cantidad de detalles que tuvo que ser dibujado. Sombras, iconos, degradados, marcos, textos.


El tiempo de dibujo está en la captura de pantalla:


 
Puede haber una manera de acelerar el dibujo. Quite la base inferior de las plataformas de las ventanas. Son grandes lienzos detrás de la parte frontal donde se encuentran los elementos. Si las quita, será 2 veces más rápido. Tendré que pensarlo.
 
¿Es posible dibujar determinadas ventanas sólo cuando están abiertas? Es raro tener una docena de ventanas abiertas a la vez. No es necesario hacerlo.
 
hini #:
¿Puedo dibujar determinadas ventanas sólo cuando están abiertas? Es raro tener decenas de ventanas abiertas al mismo tiempo. No es necesario.

Eso es lo único que ocurre, créeme. Sólo hablo del primer dibujo de todas las ventanas de la interfaz a la vez. El primer dibujo es el que más tiempo lleva. Y después de eso, todas las imágenes ya están guardadas y recuperadas de la memoria si es necesario. Con una llamada se adjuntan a sus lienzos en unos pocos milisegundos. Esto no es un problema. Sólo quieres comprimir el tiempo del primer dibujo.

 
Реter Konow #:
Puede haber una manera de acelerar el dibujo. Retire la base inferior de las plataformas de las ventanas. Se trata de grandes lonas situadas detrás de la parte frontal donde se encuentran los elementos. Si las quita, será 2 veces más rápido. Tendré que pensarlo.

Estas son las lonas de las que hablo:

1. La parte frontal donde se encuentran los elementos:


2. La parte trasera donde se encuentran los botones de la ventana (cruz, minimizador), el icono y el texto del nombre. Sin embargo, toda la ventana está coloreada en verde y se ha invertido tiempo en ella. Pero, el usuario sólo ve los marcos y la cabecera de la ventana. Resulta que en este lugar el dibujo se hace en vano: