Criar uma biblioteca gráfica a partir do zero - página 3

 
Maxim Kuznetsov:

Resumidamente, sobre engenharia :

Se houver um desejo de melhorar alguns "A" através do re-desenvolvimento, é necessário especificar suas deficiências críticas. Basta listá-los e explicar por que eles são intratáveis no processo de desenvolvimento evolutivo de A.

Por outro lado, ninguém o proíbe. Se você gosta de escrever código, escreva-o. Reescreva "A", mas à sua maneira, mas será novo

Max, olá!

Bem, eu já descrevi repetidamente as "falhas" que do meu ponto de vista vejo na biblioteca padrão e na biblioteca do Anatoly.

Ambas as bibliotecas têm, em minha opinião, uma desvantagem significativa: a interface é construída sobre objetos gráficos discretos, ou seja, quanto mais controles na interface, mais objetos isolados no próprio gráfico. Por um lado, isto não parece ser um problema, mas por outro lado é um problema com diálogos de arrastar e soltar, pois não um único objeto "forma com elementos" é arrastado e solto, mas muitos elementos diferentes. E isto consome recursos adicionais.

A biblioteca de Anatoly é muito chique, mas é complicada em sua composição e difícil de ser integrada ao programa principal. E a biblioteca padrão é limitada nos próprios controles, embora a arquitetura original seja muito boa, na minha opinião.

Na verdade, a melhor solução seria o que Petr Konov tenta fazer: construtor de GUI GUI com geração de código GUI, mas com modelo de evento estendido, assim, ao integrar com o programa principal, você não precisaria entrar em um enorme código GUI (algo como o analógico MVVM), e, claro, com objetos que os usuários poderiam expandir por conta própria.

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

Max, olá!

Bem, eu já descrevi muitas vezes as "deficiências" que, do meu ponto de vista, vejo na biblioteca padrão e na biblioteca do Anatoly.

Ambas as bibliotecas têm, em minha opinião, um inconveniente significativo: a interface é construída sobre objetos gráficos discretos, ou seja, quanto mais controles na interface, mais objetos isolados no próprio gráfico. Por um lado, isto não parece ser um problema, mas por outro lado é um problema com diálogos de arrastar e soltar, pois não um único objeto "forma com elementos" é arrastado e solto, mas muitos elementos diferentes. E isto consome recursos adicionais.

A biblioteca de Anatoly é muito chique, mas é complexa em sua composição e difícil de ser integrada ao programa principal. E a biblioteca padrão é limitada nos próprios controles, embora a arquitetura original seja muito boa, na minha opinião.

Na verdade, a melhor solução seria o que Petr Konov está tentando fazer: um construtor de GUI com geração de código GUI, mas com um modelo de evento estendido, para que ao integrar com o programa principal você não tenha que entrar em um enorme código GUI, e claro, com objetos que os usuários poderiam estender por conta própria.

a citação deve ser lida de baixo para cima. O fundo (o que é sublinhado) é mais importante. É o que define.

Com todo o desenvolvimento moderno de todas as Interfaces Humanas, é bastante surpreendente ver vistas coordenadas e formar elementos em primeiro plano.
Ao mesmo tempo, todos usam navegadores com Rest/Ajax, sabe o que é MVC, mas não pensa na interface entre o Expert Advisor e sua GUI.

Se o modelo for descrito e houver um protocolo para trabalhar com ele, a GUI pode ser qualquer coisa e não depende do Expert Advisor. Isto é algum tipo de coisa maligna, diabólica, para colocar janelas no Expert Advisor. O principal objetivo dos Consultores Especialistas é o comércio, todo o resto deve ser retirado do código principal e ser opcional.

 
Maxim Kuznetsov:

a citação deve ser lida corretamente de baixo para cima. O fundo (o que é sublinhado) é mais importante. É o que define.

Com todo o desenvolvimento moderno da Interface Humana, é bastante surpreendente ver as representações coordenadas e formar elementos em primeiro plano.
Ao mesmo tempo, todos usam navegadores com Rest/Ajax, sabe o que é MVC, mas não pensa na interface entre o Expert Advisor e sua GUI.

Se o modelo for descrito e houver um protocolo para trabalhar com ele, a GUI pode ser qualquer coisa e não depende do Expert Advisor. Isto é algum tipo de mal quando você coloca uma caixa no Expert Advisor. O principal objetivo dos Consultores Especialistas é o comércio, todo o resto deve ser retirado do código principal e ser opcional.

Acho que devemos assumir que desde o início os desenvolvedores não pensaram no fato de que a funcionalidade das interfaces poderia ser necessária. Se você se lembra, no início não havia sequer um OOP em mql, seu principal objetivo era apenas escrever indicadores e tudo foi projetado para isso.

E agora vemos que o mql já trabalhou com soquetes e bancos de dados, mesmo no nível central... Mas os mecanismos de interação entre o usuário e o programa são deixados de lado.

Os próprios desenvolvedores declararam há quase dez anos que o desenvolvimento de interfaces é um mecanismo muito importante de interação entre o usuário e a aplicação e desenvolveram uma biblioteca padrão para este caso, mas apenas sua aplicabilidade às tarefas não foi demonstrada e, de fato, ainda hoje muitos programadores não estão cientes de sua existência.

Vamos tentar eliminar as lacunas. Mesmo que outros participantes não precisem dela, uma certa experiência será adquirida de qualquer forma.

 
Alexandr Andreev:

Comecei com a sua biblioteca, obrigado por isso, depois a afinei um pouco, depois mais alguns, depois mais alguns)))) mudaram tudo, incluindo funções de linha reescritas, também funções de linha ampla da fonte Kanvas, remover funções falsas, colocar stub no evento. ainda não totalmente da estrutura W, embora também não haja muito mais. Acrescentei o cálculo da barra à esquerda e à direita por busca binária entre outros elementos e também acrescentei a própria busca binária com a capacidade de escolher maior ou menor valor. Também acrescentei a capacidade de construir a partir de arrays de qualquer tipo (timeseries/comuns) e cheguei à conclusão de que eu deveria mudar build))))))

Legal.

Sim, as bibliotecas devem ser universais para os programadores novatos, ou estritamente focadas para os mais avançados.

Eu mesmo tenho várias versões de meu próprio iCanvas para diferentes propósitos.

Foi por isso que comecei a formular uma lista de intenções e objetivos ou pelo menos a indicar a direção. E coloque esta lista no primeiro post enquanto ela estiver disponível para edição.

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

De qualquer forma, ou estou fazendo algo errado ou os modelos de declaração de classe (vazios) não querem funcionar. O que faz com que o código não seja particularmente útil.

Estou pensando em mudar

 
Um código tão bonito seria uma boa idéia para levá-lo a uma exposição. Para que serve, como e o que resolve é desconhecido, mas é muito bonito...
 
Rapazes, como vocês me ensinaram, deixem-me ensiná-los.

Você deve entender como funcionam os mecanismos da GUI em primeiro lugar, e depois começar a escrever o código. Você deve conhecer a estrutura e o comportamento dos elementos, suas reações em diferentes situações. Primeiro, apresentá-los como modelos e depois criar instâncias sobre uma base técnica preparada, incluindo modelo de evento, manipuladores de estado, fenômenos, coordenadas, encadernações e desenho. No final, você terá uma biblioteca de gráficos em bruto sobre tela. Será um longo caminho a partir de uma linguagem de marcação. Para não mencionar um editor. Mas, vá em frente.

Se você pensa que vai simplesmente pegar algo pronto e elevá-lo a um nível mais alto, então você nunca desenvolveu nada sério.
 
Реter Konow:
Rapazes, como vocês me ensinaram, deixem-me ensiná-los.

Você deve entender como funcionam os mecanismos da GUI em primeiro lugar, e depois começar a escrever o código. Você deve conhecer a estrutura e o comportamento dos elementos, suas reações em diferentes situações. Primeiro, apresentá-los como modelos e depois criar instâncias sobre uma base técnica preparada, incluindo modelo de evento, manipuladores de estado, fenômenos, coordenadas, encadernações e desenho. No final, você terá uma biblioteca de gráficos em bruto sobre tela. Será um longo caminho a partir de uma linguagem de marcação. Para não mencionar um editor. Mas, vá em frente.

Se você acha que vai simplesmente pegar algo pronto e levá-lo para cima, então você nunca desenvolveu nada sério.

Esperar para julgar - não é mais do que o básico. E o fato de que eu vou terminar a GUI é improvável - foi o que eu disse no início. Quanto aos grandes projetos - digo isto em suas linhas de código não são suficientes para competir com grandes projetos.....


agora a questão é por que o truque não 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:

...

agora a questão é por que este truque não funciona

Quem sabe por que não funciona...

O esquema da biblioteca deve ser feito primeiro, e depois os códigos devem ser escritos. É assim que geralmente é feito.