グラフィックライブラリーをゼロから作成する - ページ 4

 
Реter Konow:
なぜうまくいかないのか、誰にもわからない......。

ライブラリーの概略をまず描き、次にコードを書く。通常はこの方法で行います。

はC++で動作します。

なぜスキームが描かれていないと思うのか、その前提条件があったのでしょうか?
 
Alexandr Andreev:

はC++で動作します。

なぜスキーマがないと思うのか、その前提条件があったのでしょうか?
どこにあるんだ?3ページ目にして初めて見た。
 
Реter Konow:
どこにあるんだ?3ページ目にして初めて見た。

New_Window<<Window_Upper.Size; New_Window<<Window_Upper.Position; New_Window.Size<<0.5 (サイズが自動的に上記の半分になる); ...という最小限のコードスタイルになるような使用根拠を作ろうと考えていたのですが、どうでしょうか?

そしてこのクラスは、小クロスの位置から高い方の窓(ベース)への関係もすでに考慮されています。

どうやらスムーズにいかないようだ...。ということが起こります。
 
Alexandr Andreev:

New_Window<<Window_Upper.Size; New_Window<<Window_Upper.Position; New_Window.Size<<0.5 (サイズは自動的に上記の半分になる); ...という最小限のコードスタイルに縮小できるような使用根拠を作ろうと考えていたんです。

そしてこのクラスは、小さな十字架の位置から高い窓までの関係がすでに考慮されているのです。

えへへ、へへへ...。"家を建てるのに いくらかかるんだ?" "描こう、住もう..."

私自身も同じような考え方をしています。ただ、私はその代償として長年の苦労を払っているのです。
 
Алексей Барбашин:

...

さて、私の視点から見た標準 ライブラリとAnatolyのライブラリの「欠点」については、すでに何度も説明してきました。

どちらのライブラリも、私の意見では、1つの重大な欠点があります。 インタフェースは、離散的なチャート・オブジェクトの上に構築されています。つまり、インタフェースにコントロールが多いほど、チャート自体のオブジェクトも孤立して いるのです。それ自体は問題ないのですが、一方でダイアログをドラッグする際に、1つの「要素を持つフォーム」オブジェクトではなく、多くの異なる要素がドラッグされるため、問題が発生するのです。そして、これにはさらなるリソースが消費されます。

アナトリーのライブラリーはとてもシックですが、構成が複雑で、メインプログラムに組み込むのが難しいです。また、標準ライブラリは、オリジナルのアーキテクチャは非常に良いと思うのですが、コントロール自体に制限があります。

実際、最良の解決策はPetr Konovがやろうとしていることでしょう。GUIコード生成機能を持つGUIビルダーですが、拡張イベントモデルを備えているので、メインプログラムに統合するときに膨大なGUIコード(MVVMアナログみたいなもの)を掘り下げる必要がありませんし、もちろんユーザーが独自に拡張できるオブジェクトも備えています。

もちろん、これはグラフィカル・ライブラリの問題に対する非常に単純化された見解です。フォームのドラッグ&ドロップやカンヴァス処理ができないなど、GUIの可能性や機能が制限されるのは仕方ないことだと思います。要するに、MT-オブジェクトはプロパティが少なく、描画された要素を管理し、その多様な機能をすべてサポートするためのライブラリハンドラが十分に開発 されていないのである。MTオブジェクトの複雑さやライブラリの制御機能は、kanvasが求める最低限のレベルには達していません。

これらのライブラリをkanvas用に書き換えるということは、根本的に新しいレベルに引き上げるということであり、先験的に簡単で単純なものではあり得ません。


ZS. Anatolyは、彼のライブラリでkanvasへの道を歩み始め、MKLで初めて描画されたテーブルを作成しました。しかし、セルが半独立した要素であることや、個別に対応する難しさなどから、その構築方法は不完全なものとなっています。

アナトリーの移行にかかった費用と時間を覚えています。

 

だいたいこんな感じです。

#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
 
 

これで座標系クラスは終了です。次がどうなるのかもわからない。

ポジショニングは付けた方がいいと思いますけどね。

次、中、左、上......というスタイルで。

 
Alexandr Andreev:

こんな感じです。


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

また、これを忘れています。

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

こんな感じです。

#define  TD1 int
#define  TD2 double 

そして、それが欠けているのです。

#define  TD3 bool
#define  TD4
 void 
 
Aliaksandr Hryshyn:

そして、これが欠落しているのです。

テンプレートを使いたかったが、コンパイルできない、前ページの簡略化された例

そして、それが正確にintであり、あるenumでないことが確実でない場合、コードを修正したくない場合

また、なぜそこにboolが必要なのでしょうか?

理想は、そうであること

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

そして、TD3はありません(実際、クラス全体が2つの値用に書かれています)。コードに書かれているTDも呼び出したのはなぜか