Creare una libreria grafica da zero - pagina 4

 
Реter Konow:
Chissà perché non funziona...

Lo schema della biblioteca dovrebbe essere elaborato prima, e poi i codici scritti. Questo è di solito il modo di farlo.

funziona in C++

Cosa ti fa pensare che lo schema non sia stato redatto, c'era un prerequisito per questo?
 
Alexandr Andreev:

funziona in C++

Cosa ti fa pensare che non ci sia uno schema, c'era un prerequisito per questo?
Dove si trova? Non lo vedo da tre pagine.
 
Реter Konow:
Dove si trova? Non lo vedo da tre pagine.

Stavo pensando di fare una base da usare che si ridurrebbe a un codice minimo stile New_Window<<Window_Upper.Size; New_Window<<Window_Upper.Position; New_Window.Size<<0.5 (la dimensione diventa automaticamente la metà del precedente); ...

E questa classe tiene già conto della relazione dalla posizione della piccola croce alla finestra superiore (base).

Sembra che non andrà tutto liscio... succede.
 
Alexandr Andreev:

Stavo pensando di fare una base da usare che si ridurrebbe ad uno stile di codice minimo New_Window<<Window_Upper.Size; New_Window<<Window_Upper.Position; New_Window.Size<<0.5 (la dimensione diventa automaticamente la metà del precedente); ...

E questa classe tiene già conto della relazione tra la posizione della piccola croce e la finestra superiore.

Ehhh, heh, heh.... "cosa ci costa costruire una casa, la disegneremo, vivremo..."

Anch'io ho lo stesso approccio. Solo che lo pago con anni di duro lavoro.
 
Алексей Барбашин:

...

Beh, ho già descritto molte volte i "difetti" che dal mio punto di vista vedo nella libreria standard e in quella di Anatoly.

Entrambe le librerie hanno, a mio parere, uno svantaggio significativo: l'interfaccia è costruita su oggetti grafici discreti, cioè, più controlli nell'interfaccia, più oggetti isolati nel grafico stesso. Da un lato non è un problema in sé, ma dall'altro è un problema con le finestre di dialogo di trascinamento, poiché non viene trascinato un singolo oggetto "modulo con elementi", ma molti elementi diversi. E questo consuma risorse aggiuntive.

La libreria di Anatoly è molto chic, ma è complicata nella sua composizione e difficile da integrare nel programma principale. E la libreria standard è limitata nei controlli stessi, anche se l'architettura originale è molto buona secondo me.

In effetti, la soluzione migliore sarebbe quella che Petr Konov cerca di fare: costruttore di GUI con generazione di codice GUI, ma con modello di eventi esteso, in modo che quando si integra con il programma principale non si debba scavare in un enorme codice GUI (qualcosa come MVVM analogico), e naturalmente con oggetti che gli utenti potrebbero estendere da soli.

Naturalmente, questa è una visione molto semplificata del problema delle librerie grafiche. Non si tratta del trascinamento di moduli e della mancanza di gestione del kanvas, che limita le possibilità e la funzionalità della GUI. La linea di fondo è che gli oggetti MThanno poche proprietà, e i gestori di libreria non sono sufficientemente sviluppati per gestire gli elementi disegnati e per supportare tutte le loro diverse capacità. La complessità degli oggetti MT e la funzionalità di controllo delle librerie non raggiunge il livello minimo richiesto da kanvas.

Prendere queste librerie e riscriverle per kanvas significa portarle ad un livello fondamentalmente nuovo, che a priori non può essere facile e semplice.


ZS. Anatoly ha iniziato la strada ai kanvas nella sua biblioteca ed è stato il primo a creare tabelle disegnate in MKL. Tuttavia, il metodo per costruirli è imperfetto, a causa del fatto che le cellule sono elementi semi-indipendenti e ci sono difficoltà nell'affrontare ognuna singolarmente.

Ricordo quanto costò la transizione ad Anatoly e quanto tempo ci volle.

 

È più o meno così

#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
 
 

Questa è la fine della classe di coordinate. Non so nemmeno cosa ci sarà dopo.

Penso che dovremmo aggiungere il posizionamento, però.

Nello stile di next, in, left, top. cent.....

 
Alexandr Andreev:

Va più o meno così.


#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)

Hai anche dimenticato questo:

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

Va più o meno così.

#define  TD1 int
#define  TD2 double 

Ed è questo che manca:

#define  TD3 bool
#define  TD4
 void 
 
Aliaksandr Hryshyn:

E questo è ciò che manca:

Volevo usare dei modelli ma non si compilano, l'esempio semplificato nella pagina precedente

E non è sicuro che sarà esattamente int e non qualche enum, e quindi non si vuole correggere il codice

E perché abbiamo bisogno di un bool lì?

Idealmente, dovrebbe essere così

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

E nessun TD3 (infatti l'intera classe è scritta per due valori). Perché ho chiamato TD anche scritto nel codice

Motivazione: