从头开始创建一个图形库 - 页 3

 
Maxim Kuznetsov:

简而言之,关于工程:

如果有一种冲动想通过重新发展来改善某些 "A",就有必要明确它的关键缺点。只要列出它们,并解释为什么它们在A的进化发展过程中是难以解决的。

另一方面,没有人禁止它。如果你喜欢写代码,就写吧。用你自己的方式重写 "A",但它将是新的。

马克斯,你好!

好吧,我已经反复描述了从我的观点来看,我在标准库 和Anatoly的库中看到的 "缺陷"。

在我看来,这两个库都有一个明显的缺点:界面是建立在离散的图表对象上的,也就是说,界面中的控件越多,图表本身的离散对象就越多。一方面,这似乎不是一个问题,但另一方面,这也是拖放对话框的一个问题,因为拖放的不是一个 "有元素的表单 "对象,而是许多不同的元素。而这就会消耗额外的资源。

阿纳托利的图书馆非常别致,但它的组成很复杂,很难整合到主程序中。而标准库在控件本身上是有限的,尽管在我看来原始架构是非常好的。

实际上,最好的解决方案是Petr Konov试图做的:带有GUI代码生成的GUI生成器,但带有扩展的事件模型,所以当与主程序集成时,你不需要进入巨大的GUI代码(类似于MVVM的东西),当然还有用户可以自己扩展的对象。

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

马克斯,你好!

好吧,我已经多次描述了从我的角度来看,我在标准库 和Anatoly的库中看到的 "缺点"。

在我看来,这两个库都有一个明显的缺点:界面是建立在离散的图表对象上的,也就是说,界面中的控件越多,图表本身的孤立对象就越多。一方面,这似乎不是一个问题,但另一方面,这也是拖放对话框的一个问题,因为拖放的不是一个 "有元素的表单 "对象,而是许多不同的元素。而这就会消耗额外的资源。

阿纳托利的图书馆非常别致,但它的组成很复杂,很难整合到主程序中。而标准库在控件本身上是有限的,尽管在我看来原始架构是非常好的。

事实上,最好的解决方案是Petr Konov正在努力做的:一个具有GUI代码生成功能的GUI生成器,但有一个扩展的事件模型,这样在与主程序集成时,就不必进入巨大的GUI代码,当然还有用户可以自己扩展的对象

这句话应该从下往上读。底部(下划线的内容)更重要。这是决定性的一条。

随着所有现代人机界面的发展,看到坐标视图和形式元素出现在前台是相当令人惊讶的。
同时,每个人都使用带有Rest/Ajax的浏览器,知道什么是MVC,但却没有考虑到专家顾问和其GUI之间的接口。

如果对模型进行了描述,并且有一个与之合作的协议,那么GUI可以是任何东西,并且不依赖于专家顾问。当你把窗口放入专家顾问时,这是某种邪恶。专家顾问的主要目的是交易,其他一切都应从主代码中抽出,成为可有可无的。

 
Maxim Kuznetsov:

这句话应该从下到上正确阅读。底部(下划线的内容)更重要。它是决定性的。

随着现代人机界面的发展,看到坐标表示和形式元素出现在前台是相当令人惊讶的。
同时,每个人都使用带有Rest/Ajax的浏览器,知道什么是MVC,但却没有考虑到专家顾问和其GUI之间的接口。

如果对模型进行了描述,并且有一个与之合作的协议,那么GUI可以是任何东西,并且不依赖于专家顾问。当你在专家顾问中放一个盒子时,这是某种邪恶。专家顾问的主要目的是交易,其他一切都应从主代码中抽出,成为可有可无的。

我认为我们应该假定,从一开始,开发人员就没有考虑到可能需要接口功能的事实。如果你还记得,在早期,mql中甚至没有任何OOP,它的主要目的只是为了写指标,一切都为它而设计。

而现在我们看到,mql已经与套接字和数据库合作,甚至在核心层面...但用户和程序之间的互动机制却被抛在一边。

开发人员自己几乎在十年前就宣布,开发接口是用户和应用程序之间非常重要的互动机制,并为这种情况开发了一个标准库,但只是它对任务的适用性没有显示出来,事实上,即使在今天,许多程序员都没有意识到它的存在。

我们将努力消除这些差距。即使其他参与者不需要它,但无论如何也会获得一定的经验。

 
Alexandr Andreev:

我从你的库开始,谢谢你,然后我调整了一下,然后又调整了一些,然后又调整了一些)))),改变了所有的东西,包括重写的行函数,还从Kanvas的源码中提取了宽行函数,删除了假函数,在事件上放了存根。还没有完全脱离W结构,虽然也没有留下多少。我在其他元素中加入了通过二进制搜索计算左边和右边的条形,还加入了二进制搜索本身,可以选择更大或更小的值。还增加了从任何类型的数组(时间序列/普通)建立的能力,并得出结论,我应该改变structure))))))。

酷。

是的,库应该是通用的,适合新手程序员,或者是狭义的,适合更高级的程序员。

我自己有几个版本的iCanvas,用于不同的目的。

这就是为什么我开始制定一份意图和目标清单,或者至少指明方向。并把这份名单放在第一篇文章中,同时可以进行编辑。

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

总之,不是我做错了什么,就是类声明(空)模板不想工作。这使得该代码不是特别方便。

我正在考虑改变

 
这样一个美丽的代码将是一个好主意,可以把它带到一个展览上。它是用来做什么的,怎么做,解决什么问题都不知道,但它非常漂亮...
 
伙计们,既然你们教我,让我来教你们。

你应该首先了解GUI机制是如何工作的,然后再开始写代码。你应该知道元素的结构和行为,它们在不同情况下的反应。首先,将它们作为模板呈现,然后在准备好的技术基础上创建实例,包括事件模型、状态处理程序、现象、坐标、绑定和绘图。最后,你将拥有一个画布上的原始图形库。它与标记语言将有很大的距离。更不用说一个编辑了。但是,去吧。

如果你认为你只是将现成的东西,提高到一个更高的水平,那么你从来没有认真开发过任何东西。
 
Реter Konow:
伙计们,既然你们教我,让我来教你们。

你应该首先了解GUI机制是如何工作的,然后再开始写代码。你应该知道元素的结构和行为,它们在不同情况下的反应。首先,将它们作为模板呈现,然后在准备好的技术基础上创建实例,包括事件模型、状态处理程序、现象、坐标、绑定和绘图。最后,你将拥有一个画布上的原始图形库。它与标记语言将有很大的距离。更不用说一个编辑了。但是,去吧。

如果你认为你只是把现成的东西拿出来,然后把它提高一个档次,那么你从来没有认真开发过任何东西。

等待判断--它甚至没有超过基本的东西。而我将完成GUI的事实是不可能的--这是我在一开始就说过的。至于大型项目--我这么说是在你的代码行不足以与大型项目竞争.....。


现在的问题是,为什么这一招不起作用?

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:

...

现在的问题是,为什么这一招不起作用?

谁知道它为什么不起作用...

应首先创建库的模式,然后再编写代码。这就是通常的做法。