Crear una biblioteca gráfica desde cero - página 3

 
Maxim Kuznetsov:

Brevemente, sobre la ingeniería :

Si se quiere mejorar alguna "A" por medio de la reelaboración, es necesario especificar sus defectos críticos. Sólo hay que enumerarlas y explicar por qué son intratables en el proceso de desarrollo evolutivo de A.

Por otro lado, nadie lo prohíbe. Si te gusta escribir código, escríbelo. Reescribe "A" pero a tu manera, pero será nuevo

¡Max, hola!

Bueno ya he descrito repetidamente los "defectos" que desde mi punto de vista veo en la biblioteca estándar y en la biblioteca de Anatoly.

Ambas bibliotecas tienen, en mi opinión, un inconveniente importante: la interfaz se construye sobre objetos de gráfico discretos, es decir, cuantos más controles haya en la interfaz, más objetos aislados habrá en el propio gráfico. Por un lado esto no parece ser un problema, pero por otro lado es un problema con los diálogos de arrastrar y soltar, ya que no se arrastra y suelta un solo objeto "formulario con elementos", sino muchos elementos diferentes. Y esto consume recursos adicionales.

La biblioteca de Anatoly es muy elegante, pero es complicada en su composición y difícil de integrar en el programa principal. Y la biblioteca estándar es limitada en los controles mismos, aunque la arquitectura original es muy buena en mi opinión.

De hecho, la mejor solución sería lo que Petr Konov intenta hacer: constructor de GUI con generación de código de GUI, pero con modelo de eventos extendido, de modo que al integrarse con el programa principal, no sería necesario entrar en un enorme código de GUI (algo así como la analogía de MVVM), y por supuesto con objetos que los usuarios podrían ampliar por su cuenta.

 
Алексей Барбашин:

¡Max, hola!

Bueno, ya he descrito muchas veces las "carencias" que, desde mi punto de vista, veo en la biblioteca estándar y en la de Anatoly.

Ambas bibliotecas tienen, en mi opinión, un inconveniente importante: la interfaz se construye sobre objetos de gráfico discretos, es decir, cuantos más controles haya en la interfaz, más objetos aislados habrá en el propio gráfico. Por un lado esto no parece ser un problema, pero por otro lado es un problema con los diálogos de arrastrar y soltar, ya que no se arrastra y suelta un solo objeto "formulario con elementos", sino muchos elementos diferentes. Y esto consume recursos adicionales.

La biblioteca de Anatoly es muy elegante, pero es compleja en su composición y difícil de integrar en el programa principal. Y la biblioteca estándar es limitada en los controles mismos, aunque la arquitectura original es muy buena en mi opinión.

De hecho, la mejor solución sería lo que Petr Konov está intentando hacer: un constructor de GUI con generación de código de GUI, pero con un modelo de eventos extendido, para que al integrarse con el programa principal no haya que entrar en un código de GUI enorme, y por supuesto con objetos que los usuarios puedan extender por su cuenta.

la cita debe leerse de abajo a arriba. El fondo (lo que está subrayado) es más importante. Es la que define.

Con todo el desarrollo moderno de todas las interfaces humanas, es bastante sorprendente ver las vistas de coordenadas y los elementos de forma en primer plano.
Al mismo tiempo todo el mundo utiliza navegadores con Rest/Ajax, sabe lo que es MVC, pero no piensa en la interfaz entre el Asesor Experto y su GUI.

Si el modelo está descrito y existe un protocolo para trabajar con él, la interfaz gráfica puede ser cualquier cosa y no depende del Asesor Experto. Esto es una especie de maldad cuando se ponen ventanas en el Asesor Experto. El propósito principal de los Asesores Expertos es el comercio, todo lo demás debe ser sacado del código principal y ser opcional.

 
Maxim Kuznetsov:

la cita debe leerse correctamente de abajo a arriba. El fondo (lo que está subrayado) es más importante. Es la que define.

Con todo el desarrollo moderno de la Interfaz Humana, es bastante sorprendente ver representaciones de coordenadas y elementos de forma en primer plano.
Al mismo tiempo todo el mundo utiliza navegadores con Rest/Ajax, sabe lo que es MVC, pero no piensa en la interfaz entre el Asesor Experto y su GUI.

Si el modelo está descrito y existe un protocolo para trabajar con él, la interfaz gráfica puede ser cualquier cosa y no depende del Asesor Experto. Esto es una especie de maldad, maldad-maldad para poner ventanas en el Asesor Experto. El propósito principal de los Asesores Expertos es el comercio, todo lo demás debe ser sacado del código principal y ser opcional.

Creo que debemos asumir que desde el principio los desarrolladores no pensaron en el hecho de que la funcionalidad de las interfaces podría ser necesaria. Si recuerdas, en los primeros días no había ni siquiera OOP en mql, su propósito principal era sólo escribir indicadores y todo estaba diseñado para ello.

Y ahora vemos que mql ya ha trabajado con sockets y bases de datos, incluso a nivel del núcleo... Pero los mecanismos de interacción entre el usuario y el programa se dejan de lado.

Los propios desarrolladores han declarado hace casi diez años que el desarrollo de interfaces es un mecanismo muy importante de la interacción entre el usuario y la aplicación y han desarrollado una biblioteca estándar para este caso, pero sólo su aplicabilidad a las tareas no han demostrado y, de hecho, incluso hoy en día muchos programadores no son conscientes de su existencia.

Intentaremos eliminar las lagunas. Aunque los demás participantes no lo necesiten, se ganará cierta experiencia de todos modos.

 
Alexandr Andreev:

Empecé con tu librería, gracias por ello, luego la retoqué un poco, luego algo más, luego algo más)))) cambié todo incluyendo funciones de línea reescritas, también función de línea ancha de la fuente de Kanvas, eliminé funciones falsas, puse stub en el evento. aún no se ha ido completamente de la estructura W aunque tampoco queda mucho allí. He añadido el cálculo de la barra a la izquierda y a la derecha mediante la búsqueda binaria entre otros elementos y también he añadido la búsqueda binaria en sí misma con la posibilidad de elegir un valor mayor o menor. También se ha añadido la posibilidad de construir a partir de arrays de cualquier tipo (timeseries/common ) Y he llegado a la conclusión de que debería cambiar construct))))))

Genial.

Sí, las bibliotecas deben ser universales para los programadores principiantes, o bien estar enfocadas para los más avanzados.

Yo mismo tengo varias versiones de mi propio iCanvas para diferentes propósitos.

Por eso empecé a formular una lista de intenciones y objetivos, o al menos a indicar la dirección. Y pon esta lista en el primer post mientras esté disponible para su edición.

 
//whats TD (template define)? because TT is busy
//почемуто этот код в шаблонах на мкл не хочет компилироваться поэтому через дефайн - это Плохо надо бы через шаблоны как то придумать.... привет метаквотам
#define  TD1 int
#define  TD2 double 
#define  EMPY -1 
#define  GET this.operator>> 
#define  SET this.operator<< 
class CCoordD; 
class CSizeD;
class CCoordBaseD //полностью внутрений класс
   {
   private:
   #define  ME CCoordBaseD 
   TEMPL1(T)
   bool Chek(T *a)                  {return CheckPointer(a)!=POINTER_INVALID;}
   TEMPL1(T)
   bool Chek(T a)                   {return a!=(T)EMPY;}
   TD1 Error()                      {Print(__FUNCTION__," ",__LINE__," POINTER_INVALID size"); int a[]; a[0]=0; return (TD1)EMPY;};//wtf??? =P CRASH Error
   TD1 GetA()                       {return c.GetA()+ar;}
   TD1 GetP()                       {return c.Result() + size.GetP()*(TD1)pr;}
   public:
   ME()                                   {Init();} 
   ME(TD1 a)                              {Init(a);} 
   ME(TD1 a,CCoordD &b)                   {Init(a,b);} 
   ME(TD1 a,CCoordD &b,CSizeD &x)         {Init(a,b,x);} 
   ME(TD2 a,CSizeD &b)                    {Init(a,b);} 
   ME(TD2 a,CCoordD &b,CSizeD &x)         {Init(a,b,x);} 
   CCoordD *c;//one coord
   CSizeD *size;//size 
   TD1 ar;
   TD2 pr;//percent проценты
   void Init()                            {ar=(TD1)EMPY; pr=(TD2)EMPY; }  
   TD1 Result()                           {return Chek(ar)?Chek(c)?GetA():ar:Chek(pr)?Chek(size)?GetP():Error():(TD1)EMPY;}
   ME *GetMe()                            {return &this;}
   ME *GetCoorBase()                      {return c;}
   ME *GetSizeBase()                      {return size;} 
   CCoordD *GetCoor()                     {return c;}
   CSizeD *GetSize()                      {return size;} 
   void Init(TD1 a)                       {Init(); SET(a);}
   void Init(TD1 a,CCoordD &b)            {Init(); SET(a); SET(b);}
   void Init(TD1 a,CCoordD &b,CSizeD &x)  {Init(); SET(a); SET(b); SET(x);}
 //  void Init(TD2 p)                     {Init(); pr=p_;}
   void Init(TD2 a,CSizeD &b)             {Init(); SET(a); SET(b);}
   void Init(TD2 a,CCoordD &b,CSizeD &x)  {Init(); SET(a); SET(b); SET(x);}
   void operator >> (TD1 &a)              {a=ar;} 
   void operator >> (TD2 &a)              {a=pr;}  
   void operator >> (CCoordD &a)          {a=GetPointer(c);}  
   void operator >> (CSizeD &s)           {s=GetPointer(size);}  
   void operator << (TD1 &a)              {ar=a;} 
   void operator << (TD2 &a)              {pr=a;}  
   void operator << (CCoordD &a)          {c=GetPointer(a);}  
   void operator << (CSizeD &s)           {size=GetPointer(s);}  
   void operator << (ME &a)               {a>>c; a>>ar; a>>pr; a>>size;}  
   void operator = (CCoordD &a)           {SET(a);}
   void operator = (CSizeD &a)            {SET(a);}
   void operator = (ME &a)                {SET(a);} 
   #undef  ME
   #undef  TD1
   #undef  TD2
   #undef  GET 
   #undef  SET
   };
   
class CSizeD : public CCoordBaseD
   {
   public:
   CSizeD(){};
   };
   
class CCoordD : public CCoordBaseD
   {
   public:
   CCoordD(){};
   };

class CTX {public:CTX(){}}; 
class CTY {public:CTY(){}};
class CTZ {public:CTZ(){}};
TEMPL(T)
class CCoordA : public T
   {
   public:
   CCoordA() {};
   CSizeD size;
   CCoordD ar; 
   void operator <<(CSizeD &a)   {return ;}
   void operator <<(CCoordD &a)  {return ;}
   };
   
class CCoord
   {  
   public: 
   CCoordA<CTX> X;
   CCoordA<CTY> Y; 
   CCoord ()                              {} 
   bool MouseOn(CMouse &mouse)//px
      {
      //return X.ar.Result()<=mouse.X && X.ar.Result()+X.size.Result()>=mouse.X && GetY()<=mouse.Y && GetY()+GetH()>=mouse.Y;
      return false;
      }
   };  
 

En fin, o estoy haciendo algo mal o las plantillas de declaración de clases (vacías) no quieren funcionar. Lo que hace que el código no sea especialmente práctico.

Estoy pensando en cambiar

 
Un código tan bonito sería la mejor manera de llevarlo a una exposición. Se desconoce para qué sirve, cómo y qué resuelve, pero es muy bonito...
 
Chicos, ya que me habéis enseñado, dejad que os enseñe yo.

En primer lugar, hay que entender cómo funcionan los mecanismos de la interfaz gráfica de usuario, y luego empezar a escribir el código. Debes conocer la estructura y el comportamiento de los elementos, sus reacciones en diferentes situaciones. Primero, preséntalos como plantillas, y luego crea instancias sobre una base técnica preparada, incluyendo el modelo de eventos, los manejadores de estado, los fenómenos, las coordenadas, los enlaces y el dibujo. Al final, tendrás una biblioteca de gráficos en bruto en el lienzo. Estará muy lejos de ser un lenguaje de marcado. Por no hablar de un editor. Pero, vete a por ello.

Si piensas que simplemente vas a tomar algo ya hecho y elevarlo a un nivel superior, entonces nunca has desarrollado nada serio.
 
Реter Konow:
Chicos, ya que me habéis enseñado, dejad que os enseñe yo.

En primer lugar, hay que entender cómo funcionan los mecanismos de la interfaz gráfica de usuario, y luego empezar a escribir el código. Debes conocer la estructura y el comportamiento de los elementos, sus reacciones en diferentes situaciones. Primero, preséntalos como plantillas, y luego crea instancias sobre una base técnica preparada, incluyendo el modelo de eventos, los manejadores de estado, los fenómenos, las coordenadas, los enlaces y el dibujo. Al final, tendrás una biblioteca de gráficos en bruto en el lienzo. Estará muy lejos de ser un lenguaje de marcado. Por no hablar de un editor. Pero, vete a por ello.

Si crees que vas a coger algo ya hecho y subirlo de nivel, es que nunca has desarrollado nada serio.

Espere a juzgar - no es más que lo básico. Y el hecho de que termine la interfaz gráfica de usuario es poco probable, eso es lo que dije al principio. En cuanto a los grandes proyectos - lo digo en sus líneas de código no son suficientes para competir con los grandes proyectos.....


ahora la pregunta es por qué el truco no funciona

class CB; 
class CC;

class CBx{public: CBx(){};};
class CBy{public: CBy(){};};
TEMPL(T) 
class CA : public T
   {
   public:
   CA(){}
   CB<T> *b;
   CC<T> *c;
   };
    
TEMPL(T) 
class CB : public CA<T>
   {
   public:
   CB(){}
   };
    
TEMPL(T) 
class CC : public CA<T>
   {
   public:
   CC(){}
   }; 

CB<CBy> cc;
 
Alexandr Andreev:

...

ahora la pregunta es por qué este truco no funciona

Quién sabe por qué no funciona...

Primero hay que hacer el esquema de la biblioteca y luego escribir los códigos. Así es como se suele hacer.