Creare una libreria grafica da zero - pagina 3

 
Maxim Kuznetsov:

Brevemente, sull'ingegneria:

Se c'è l'urgenza di migliorare qualche "A" con un nuovo sviluppo, è necessario specificare le sue debolezze critiche. Basta elencarli e spiegare perché sono intrattabili nello sviluppo evolutivo di "A".

D'altra parte, nessuno lo proibisce. Se vi piace scrivere codice, scrivetelo. Riscrivi "A" ma a modo tuo, ma sarà nuovo

Max, ciao!

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

Entrambe le librerie hanno, secondo me, uno svantaggio significativo: l'interfaccia è costruita su oggetti grafici discreti, cioè più controlli nell'interfaccia, più oggetti isolati nel grafico stesso. Da un lato questo non sembra essere un problema, 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 è complessa 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, così quando si integra con il programma principale, non sarebbe necessario entrare in un enorme codice GUI (qualcosa come l'analogia MVVM), e naturalmente con oggetti che gli utenti potrebbero espandere da soli.

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

Max, ciao!

Bene, ho già descritto molte volte le "carenze" che, dal mio punto di vista, vedo nella libreria standard e in quella di Anatoly.

Entrambe le librerie hanno, secondo me, uno svantaggio significativo: l'interfaccia è costruita su oggetti grafici discreti, cioè più controlli nell'interfaccia, più oggetti isolati nel grafico stesso. Da un lato questo non sembra essere un problema, 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 è complessa 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 sta cercando di fare: un costruttore di GUI con generazione di codice GUI, ma con un modello di eventi esteso, in modo che quando si integra con il programma principale non si debba andare in un enorme codice GUI, e naturalmente con oggetti che gli utenti potrebbero estendere per conto loro.

la citazione va letta dal basso verso l'alto. Il fondo (ciò che è sottolineato) è più importante. È quello che definisce la situazione.

Con tutto lo sviluppo moderno di tutte le interfacce umane, è piuttosto sorprendente vedere le viste coordinate e gli elementi di forma in primo piano.
Allo stesso tempo tutti usano browser con Rest/Ajax, sanno cos'è MVC, ma non pensano all'interfaccia tra l'Expert Advisor e la sua GUI.

Se il modello è descritto e c'è un protocollo per lavorare con esso, la GUI può essere qualsiasi cosa e non dipende dall'Expert Advisor. Questo è una specie di male quando si mettono le finestre nell'Expert Advisor. Lo scopo principale degli Expert Advisors è il commercio, tutto il resto dovrebbe essere tolto dal codice principale ed essere opzionale.

 
Maxim Kuznetsov:

la citazione deve essere letta correttamente dal basso verso l'alto. Il fondo (ciò che è sottolineato) è più importante. È quello che definisce.

Con tutto lo sviluppo moderno dell'interfaccia umana, è abbastanza sorprendente vedere rappresentazioni di coordinate ed elementi di forma in primo piano.
Allo stesso tempo tutti usano browser con Rest/Ajax, sanno cos'è MVC, ma non pensano all'interfaccia tra l'Expert Advisor e la sua GUI.

Se il modello è descritto e c'è un protocollo per lavorare con esso, la GUI può essere qualsiasi cosa e non dipende dall'Expert Advisor. Questo è una specie di male quando si mette una casella nell'Expert Advisor. Lo scopo principale degli Expert Advisors è il commercio, tutto il resto dovrebbe essere tolto dal codice principale ed essere opzionale.

Penso che dovremmo supporre che fin dall'inizio gli sviluppatori non abbiano pensato al fatto che la funzionalità delle interfacce potesse essere necessaria. Se vi ricordate, nei primi tempi non c'era nemmeno una OOP in mql, il suo scopo principale era solo quello di scrivere indicatori e tutto era progettato per questo.

E ora vediamo che mql ha già lavorato con socket e database, anche a livello di core... Ma i meccanismi di interazione tra l'utente e il programma sono lasciati da parte.

Gli stessi sviluppatori hanno dichiarato quasi dieci anni fa che lo sviluppo di interfacce è un meccanismo molto importante di interazione tra l'utente e l'applicazione e hanno sviluppato una libreria standard per questo caso, ma solo la sua applicabilità ai compiti non hanno mostrato e infatti ancora oggi molti programmatori non sono consapevoli della sua esistenza.

Cercheremo di eliminare le lacune. Anche se gli altri partecipanti non ne avranno bisogno, una certa esperienza sarà comunque acquisita.

 
Alexandr Andreev:

Ho iniziato con la tua libreria, grazie per questo, poi l'ho modificata un po', poi un po' di più, poi un po' di più)))) cambiato tutto, comprese le funzioni di linea riscritte, anche la funzione di linea larga dal sorgente Kanvas, rimosso le funzioni false, messo lo stub sull'evento. non ancora completamente andato dalla struttura W anche se non è rimasto molto neanche lì. Ho aggiunto il calcolo della barra a sinistra e a destra tramite la ricerca binaria tra altri elementi e ho anche aggiunto la ricerca binaria stessa con la possibilità di scegliere un valore maggiore o minore. Ho anche aggiunto la possibilità di costruire da array di qualsiasi tipo (serie temporali/comuni) e sono giunto alla conclusione che dovrei cambiare costrutto))))))

Fico.

Sì, le librerie dovrebbero essere o universali per i programmatori principianti, o strettamente focalizzate per i più avanzati.

Io stesso ho diverse versioni del mio iCanvas per diversi scopi.

Ecco perché ho iniziato a formulare una lista di intenzioni e obiettivi o almeno a indicare la direzione. E mettete questa lista nel primo post mentre è disponibile per la modifica.

 
//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;
      }
   };  
 

Comunque, o sto facendo qualcosa di sbagliato o i modelli di dichiarazione di classe (vuoti) non vogliono funzionare. Il che rende il codice non particolarmente pratico.

Sto pensando di cambiare

 
Un codice così bello sarebbe una buona idea portarlo a una mostra. A cosa serve, come e cosa risolve non si sa, ma è molto bello...
 
Ragazzi, visto che mi avete insegnato voi, lasciate che vi insegni io.

Dovreste innanzitutto capire come funzionano i meccanismi delle GUI, e poi iniziare a scrivere codice. Dovresti conoscere la struttura e il comportamento degli elementi, le loro reazioni in diverse situazioni. In primo luogo, presentarli come modelli, e poi creare istanze su una base tecnica preparata, compreso il modello di eventi, i gestori di stato, i fenomeni, le coordinate, i binding e il disegno. Alla fine, avrete una libreria grafica grezza su tela. Sarà molto lontano da un linguaggio di markup. Per non parlare di un editore. Ma, vai pure.

Se pensate di prendere qualcosa di già pronto e portarlo ad un livello superiore, allora non avete mai sviluppato nulla di serio.
 
Реter Konow:
Ragazzi, visto che mi avete insegnato voi, lasciate che vi insegni io.

Dovreste innanzitutto capire come funzionano i meccanismi delle GUI, e poi iniziare a scrivere codice. Dovresti conoscere la struttura e il comportamento degli elementi, le loro reazioni in diverse situazioni. In primo luogo, presentarli come modelli, e poi creare istanze su una base tecnica preparata, compreso il modello di eventi, i gestori di stato, i fenomeni, le coordinate, i binding e il disegno. Alla fine, avrete una libreria grafica grezza su tela. Sarà molto lontano da un linguaggio di markup. Per non parlare di un editore. Ma, vai pure.

Se pensate di prendere qualcosa di già pronto e portarlo in alto, allora non avete mai sviluppato niente di serio.

Aspettate a giudicare - non è nemmeno più delle basi. E il fatto che finirò la GUI è improbabile - è quello che ho detto all'inizio. Per quanto riguarda i grandi progetti - lo dico nella vostra linea di codice non sono sufficienti per competere con i grandi progetti.....


ora la domanda è perché il trucco non funziona

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:

...

ora la domanda è perché questo trucco non funziona

Chissà perché non funziona...

Lo schema della biblioteca dovrebbe essere fatto prima, e poi i codici dovrebbero essere scritti. Questo è il modo in cui si fa di solito.
Motivazione: