Erstellen einer Grafikbibliothek von Grund auf - Seite 4

 
Реter Konow:
Wer weiß, warum es nicht funktioniert...

Zuerst sollte das Schema der Bibliothek erstellt und dann der Code geschrieben werden. Dies ist in der Regel der richtige Weg.

arbeitet in C++

Wie kommen Sie darauf, dass der Plan nicht ausgearbeitet wurde, gab es dafür eine Voraussetzung?
 
Alexandr Andreev:

arbeitet in C++

Wie kommen Sie darauf, dass es kein Schema gibt, gab es dafür eine Voraussetzung?
Wo ist sie? Ich habe es seit drei Seiten nicht mehr gesehen.
 
Реter Konow:
Wo ist sie? Ich habe es seit drei Seiten nicht mehr gesehen.

Ich dachte an eine Grundlage für die Verwendung, die auf minimale Code-Stil New_Window<<<Window_Upper.Size; New_Window<<Window_Upper.Position; New_Window.Size<<0.5 (Größe wird automatisch die Hälfte der oben genannten); ... reduziert werden würde.

Und diese Klasse berücksichtigt bereits die Beziehung zwischen der Position des kleinen Kreuzes und dem höheren Fenster (Basis).

Sieht so aus, als würde es nicht reibungslos ablaufen... passiert es.
 
Alexandr Andreev:

Ich dachte daran, eine Grundlage für die Verwendung, die auf minimale Code-Stil New_Window<<<Window_Upper.Size; New_Window<<<Window_Upper.Position; New_Window.Size<<<0.5 (Größe wird automatisch die Hälfte der oben); reduziert werden würde.

Und diese Klasse berücksichtigt bereits die Beziehung zwischen der Position des kleinen Kreuzes und dem höheren Fenster.

Ehhh, heh, heh.... "Was kostet es uns, ein Haus zu bauen, wir werden es zeichnen, wir werden leben..."

Ich selbst verfolge den gleichen Ansatz. Nur ich bezahle dafür mit jahrelanger harter Arbeit.
 
Алексей Барбашин:

...

Nun, ich habe bereits mehrfach die "Mängel" beschrieben, die ich aus meiner Sicht in der Standardbibliothek und in Anatolys Bibliothek sehe.

Beide Bibliotheken haben meiner Meinung nach einen entscheidenden Nachteil:Die Schnittstelle ist auf diskreten Diagrammobjekten aufgebaut, d.h. je mehr Steuerelemente in der Schnittstelle, desto mehr isolierte Objekte im Diagramm selbst. Einerseits ist das an sich kein Problem, aber andererseits ist es ein Problem beim Ziehen der Dialoge, da nicht ein einzelnes "Formular mit Elementen"-Objekt gezogen wird, sondern viele verschiedene Elemente. Und das verbraucht zusätzliche Ressourcen.

Die Bibliothek von Anatoly ist sehr schick, aber sie ist komplex in ihrer Zusammensetzung und schwer in das Hauptprogramm zu integrieren. Und die Standardbibliothek ist bei den Steuerelementen selbst begrenzt, obwohl die ursprüngliche Architektur meiner Meinung nach sehr gut ist.

In der Tat wäre die beste Lösung, was Petr Konov versucht zu tun: GUI GUI Builder mit GUI-Code-Generierung, aber mit erweiterten Event-Modell, so dass bei der Integration mit dem Hauptprogramm, würden Sie nicht zu graben in riesigen GUI-Code (so etwas wie MVVM analog), und natürlich mit Objekten, die Benutzer könnten auf ihre eigenen erweitern.

Dies ist natürlich eine sehr vereinfachte Sicht auf das Thema grafische Bibliotheken. Es geht nicht um das Ziehen und Ablegen von Formularen und das Fehlen eines Kanvas, was die Möglichkeiten und die Funktionalität der GUI einschränkt. Unterm Strichhaben MT-Objektenur wenige Eigenschaften, und die Bibliotheks-Handler sind nicht ausreichend entwickelt, um die gezeichneten Elemente zu verwalten und all ihre vielfältigen Fähigkeiten zu unterstützen. Die Komplexität der MT-Objekte und die Steuerungsfunktionalität der Bibliotheken erreichen nicht das für Kanvas erforderliche Mindestniveau.

Diese Bibliotheken zu übernehmen und für Kanvas umzuschreiben bedeutet, sie auf ein grundlegend neues Niveau zu heben, was a priori nicht leicht und einfach sein kann.


ZS. Anatoly begann den Weg zu Kanvas in seiner Bibliothek und war der erste, der gezeichnete Tabellen in MKL erstellte. Die Methode, sie zu konstruieren, ist jedoch unvollkommen, da es sich bei den Zellen um halb unabhängige Elemente handelt und es schwierig ist, jede Zelle einzeln zu behandeln.

Ich weiß noch, was die Umstellung Anatoly kostete und wie lange sie dauerte.

 

Es ist mehr oder weniger wie folgt

#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
 
 

Das ist das Ende der Koordinatenklasse. Ich weiß nicht einmal, was als Nächstes kommt.

Ich denke aber, wir sollten die Positionierung hinzufügen.

Im Stil von next, in, left, top. cent.....

 
Alexandr Andreev:

Es geht ungefähr so.


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

Sie haben auch dies vergessen:

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

Es geht ungefähr so.

#define  TD1 int
#define  TD2 double 

Und das ist es, was fehlt:

#define  TD3 bool
#define  TD4
 void 
 
Aliaksandr Hryshyn:

Und das ist es, was noch fehlt:

Ich wollte Vorlagen verwenden, aber sie lassen sich nicht kompilieren, das vereinfachte Beispiel auf der vorherigen Seite

Und es ist nicht sicher, dass es genau int und nicht irgendeine Aufzählung sein wird, und dann will man den Code nicht korrigieren

Und warum brauchen wir dort ein bool?

Idealerweise sollte es so sein

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

Und kein TD3 (tatsächlich ist die gesamte Klasse für zwei Werte geschrieben). Warum habe ich TD auch in den Code geschrieben