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

 
Реter Konow:
Quién sabe por qué no funciona...

Primero hay que elaborar el esquema de la biblioteca y luego escribir los códigos. Esta suele ser la forma de hacerlo.

funciona en C++

¿Qué te hace pensar que el esquema no se elaboró, había un requisito previo para ello?
 
Alexandr Andreev:

funciona en C++

¿Qué te hace pensar que no hay un esquema, había un requisito previo para ello?
¿Dónde está? No lo he visto en tres páginas.
 
Реter Konow:
¿Dónde está? No lo he visto en tres páginas.

Estaba pensando en hacer una base de uso que se redujera a un estilo de código mínimo Nueva_Ventana<<Ventana_Superior.Tamaño; Nueva_Ventana<<Ventana_Superior.Posición; Nueva_Ventana.Tamaño<<0.5 (el tamaño se convierte automáticamente en la mitad de lo anterior); ...

Y esta clase ya tiene en cuenta la relación desde la posición de la cruz pequeña hasta la ventana superior (base).

Parece que no va a salir bien... sucede.
 
Alexandr Andreev:

Estaba pensando en hacer una base de uso que se redujera a un estilo de código mínimo Nueva_Ventana<<Ventana_Superior.Tamaño; Nueva_Ventana<<Ventana_Superior.Posición; Nueva_Ventana.Tamaño<<0.5 (el tamaño se convierte automáticamente en la mitad de lo anterior); ...

Y esta clase ya tiene en cuenta la relación desde la posición de la cruz pequeña hasta la ventana superior.

Ehhh, heh, heh.... "qué nos cuesta construir una casa, la dibujaremos, viviremos..."

Yo también tengo el mismo enfoque. Sólo que lo pago con años de trabajo duro.
 
Алексей Барбашин:

...

Bueno ya he descrito muchas veces 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, una desventaja importante:la interfaz está construida sobre objetos de gráfico discretos, esdecir, cuantos más controles haya en la interfaz, más objetos aislados habrá en el propio gráfico. Por un lado no es un problema en sí mismo, pero por otro lado es un problema al arrastrar los diálogos, ya que no se arrastra un único 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 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 habría que escarbar en un enorme código de GUI (algo así como el análogo de MVVM), y por supuesto con objetos que los usuarios podrían extender por su cuenta.

Por supuesto, esta es una visión muy simplificada del problema de las bibliotecas gráficas. No se trata de arrastrar y soltar formularios y la falta de manejo de kanvas, que limita las posibilidades y la funcionalidad de la GUI. La conclusión es que los objetos MTtienen pocas propiedades, y los manejadores de la biblioteca no están suficientemente desarrollados para gestionar los elementos dibujados y soportar todas sus diversas capacidades. La complejidad de los objetos MT y la funcionalidad de control de las bibliotecas no alcanza el nivel mínimo requerido por kanvas.

Tomar estas bibliotecas y reescribirlas para kanvas significa elevarlas a un nivel fundamentalmente nuevo, lo que a priori no puede ser fácil y sencillo.


ZS. Anatoly inició el camino hacia los kanvas en su biblioteca y fue el primero en crear tablas dibujadas en MKL. Sin embargo, el método para construirlas es imperfecto, debido a que las células son elementos semiindependientes y hay dificultades para abordar cada una de ellas individualmente.

Recuerdo lo que le costó la transición a Anatoly y el tiempo que duró.

 

Es más o menos así

#define  TEMPLATE(T) template<typename T>
#define  TEMPLATE2(T1,T2) template<typename T1, typename T2>

#define  TEMPL(T) TEMPLATE(T)
#define  TEMPL1(T) TEMPLATE(T)
#define  TEMPL2(T,T1) TEMPLATE2(T,T1)
//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(TD1 a,CSizeD &b,CCoordD &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 Init(TD2 a,CSizeD &b,CCoordD &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);} 
   TD1 operator ~ ()                      {return Result();} 
   #undef  ME
   #undef  GET 
   #undef  SET
   };
   
class CSizeD : public CCoordBaseD
   {
   public:
   CSizeD(){};
   };
   
class CCoordD : public CCoordBaseD
   {
   public:
   CCoordD(){};
   };

class CCoord;

class CTX {public:CTX(){}}; 
class CTY {public:CTY(){}};
class CTZ {public:CTZ(){}};
TEMPL(T)
class CCoordA : public T
   {
   public:
   CCoordD ar; 
   CSizeD size;
   CCoordA()                                                {}; 
   CCoordA(TD1 a1,TD1 a2=(TD1)0)                            {Init(a1,a2);} 
   CCoordA(TD1 a1,CCoordD &c1, CSizeD &c2,TD1 a2)           {Init(a1,c1,c2,a2);}  
   CCoordA(TD1 a1,CCoordD &c1, CSizeD &c2,TD2 a2=(TD2)1)    {Init(a1,c1,c2,a2);}  
   CCoordA(TD2 a1,CCoordD &c1, CSizeD &c2,TD1 a2)           {Init(a1,c1,c2,a2);}  
   CCoordA(TD2 a1,CCoordD &c1, CSizeD &c2,TD2 a2=(TD2)1)    {Init(a1,c1,c2,a2);}   
   void Init()                                              {} 
   void Init(TD1 a1,TD1 a2=(TD1)0)                          {ar.Init(a1);        size.Init(a2);} 
   void Init(TD1 a1,CCoordD &c1, CSizeD &c2,TD1 a2)         {ar.Init(a1,c1,c2);  size.Init(a2,c1,c2);}  
   void Init(TD1 a1,CCoordD &c1, CSizeD &c2,TD2 a2=(TD2)1)  {ar.Init(a1,c1,c2);  size.Init(a2,c1,c2);}  
   void Init(TD2 a1,CCoordD &c1, CSizeD &c2,TD1 a2)         {ar.Init(a1,c1,c2);  size.Init(a2,c1,c2);}  
   void Init(TD2 a1,CCoordD &c1, CSizeD &c2,TD2 a2=(TD2)1)  {ar.Init(a1,c1,c2);  size.Init(a2,c1,c2);}  
   void operator <<(CSizeD &a)   {return ;}
   void operator <<(CCoordD &a)  {return ;} 
   bool Chek(int px)             {return (px-=(int)~ar) < 0 && px<(int)~size;}                   
   };
   
class CCoord
   {  
   public: 
   CCoordA<CTX> X;
   CCoordA<CTY> Y; 
   CCoord ()                              {} 
   void operator >> (CCoordA<CTX> &a)     {a=GetPointer(X);}
   void operator >> (CCoordA<CTY> &a)     {a=GetPointer(Y);}
   void operator << (CCoord &a)           {a>>X; a>>Y;}
   bool MouseOn(CMouse &mouse)//px
      {
      return X.Chek(mouse.X) && Y.Chek(mouse.Y);
      }
   };  
CCoord Pro1; 

void Func()
   {
   TD1 bi;//buf int
   TD1 bd;//buf double
   CCoord general;//создали класс координат некого объекта - к примеру окна дженерал
   general.X.Init((int)0,(int)1000); //установили размер
   general.Y.Init((int)0,(int)1000); 
   
   CCoord next;//создали класс координат следующего окна
   next<<general;//сделали его зависимым от главного окна
   next.X.ar<<(double)0.25;//старт по оси Х 25%, если значение типа дабл автоматически считается процент
   next.X.size<<(double)0.5;//размер окна равен 50% от главного.
   }
   #undef  TD1
   #undef  TD2
 
 

Este es el final de la clase de coordenadas. Ni siquiera sé qué es lo siguiente.

Sin embargo, creo que deberíamos añadir el posicionamiento.

En el estilo de siguiente, en, izquierda, arriba. cent.....

 
Alexandr Andreev:

Es algo así.


#define  TEMPLATE(T) template<typename T>
#define  TEMPLATE2(T1,T2) template<typename T1, typename T2>

#define  TEMPL(T) TEMPLATE(T)
#define  TEMPL1(T) TEMPLATE(T)
#define  TEMPL2(T,T1) TEMPLATE2(T,T1)

También olvidaste esto:

#define  TE(T) TEMPL(T)
#define  TE1(T) TEMPL1(T)
#define  TE2(T,T1) TEMPL2(T,T1)
 
Alexandr Andreev:

Es algo así.

#define  TD1 int
#define  TD2 double 

Y eso es lo que falta:

#define  TD3 bool
#define  TD4
 void 
 
Aliaksandr Hryshyn:

Y esto es lo que falta:

Quería usar plantillas pero no compilan, el ejemplo simplificado de la página anterior

Y no es seguro que sea exactamente int y no algún enum, y entonces no quieres corregir el código

¿Y por qué necesitamos un bool ahí?

Lo ideal sería que fuera así

enum EPX{}//px
enum EPR{}//процент
#define  TD1 EPX
#define  TD2 EPR

Y no hay TD3 (de hecho toda la clase está escrita para dos valores). Por qué llamé a TD también escrito en el código