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

 
Aliaksandr Hryshyn:

もっと見る

ウィンドウ領域上でマウスの右ボタンをクリックすると、メニューが表示されます。マウスをシフトして、左ボタンでクリックします。これにより、ウィンドウが移動します。

可能です。ちなみに、私は自分で開発・テストをしているので、その過程で偶然に遭遇するまでバグを知らないだけなのです。全部一人でやってるんですけど...。

 

以下は私の例で、添付ファイルでは3つのウィンドウが重なり合っています。

1つのウィンドウにサブウィンドウを作成するのは、このように、コードを追加することなくエンジンを使うだけです。ただし、上のボタンをクリックしたときのイベントの処理は 除く。

cStrategy_viewer::cStrategy_viewer()
  {
   int width_type=126;
   int height_type=30;
   int width_object=170;
   int height_object=22;

   my_handler.md=GetPointer(this);
   int obj_types_count=(ER_NODE_TYPE_COUNT-1);
//Основное окно
   _main_window=new cV_object_rectangle();
   _main_window.Set_property_info(vop_position_x,10);
   _main_window.Set_property_info(vop_position_y,50);
   _main_window.Set_property_info(vop_size_x,width_type*obj_types_count);
   _main_window.Set_property_info(vop_size_y,700);
   _main_window.Set_property_info(vop_is_zorder_top_on_click,true);
   _main_window.Create(cV_object_base::global_parent_object);
//Заголовок
   cV_object_rectangle *caption=new cV_object_rectangle();
   caption.Set_property_info(vop_position_x,-1);
   caption.Set_property_info(vop_position_y,-1);
   caption.Set_property_info(vop_size_x,_main_window.Get_property(vop_size_x).data_long);
   caption.Set_property_info(vop_size_y,20);
   caption.Create(_main_window);
//Текст заголовка.Будет отображаться полное имя файла стратегии
   _caption_text=new cV_object_label();
   _caption_text.Set_property_info(vop_position_x,-1);
   _caption_text.Set_property_info(vop_position_y,-1);
   _caption_text.Set_property_info(vop_size_x,caption.Get_property(vop_size_x).data_long);
   _caption_text.Set_property_info(vop_text,"Стратегия ....");
   _caption_text.Set_property_info(vop_text_anchor,TA_CENTER);
   _caption_text.Set_property_info(vop_font_size,20);
   _caption_text.Set_property_info(vop_is_movable,true);
   _caption_text.Set_property_info(vop_moving_parent_index,2);
   _caption_text.Set_property_info(vop_is_position_fixing_parent_x,true);
   _caption_text.Set_property_info(vop_is_position_fixing_parent_y,true);
   _caption_text.Set_property_info(vop_position_fixing_parent_index_x,2);
   _caption_text.Set_property_info(vop_position_fixing_parent_index_y,2);
   _caption_text.Create(caption);
//Контейнер для типов объектов
   _object_types=new cV_object_base();
   _object_types.Set_property_info(vop_position_x,0);
   _object_types.Set_property_info(vop_position_y,20);
   _object_types.Set_property_info(vop_size_x,obj_types_count*width_type);
   _object_types.Set_property_info(vop_size_y,height_type);
   _object_types.Create(_main_window);
//Типы объектов
   cV_object_rectangle *obje_type;
   cV_object_label *obje_type_text;
   for(int i1=0; i1<obj_types_count; i1++)
     {
      obje_type=new cV_object_rectangle();
      obje_type.Set_property_info(vop_position_x,i1*width_type);
      obje_type.Set_property_info(vop_position_y,0);
      obje_type.Set_property_info(vop_size_x,width_type);
      obje_type.Set_property_info(vop_size_y,height_type);
      obje_type.Set_property_info(vop_border_line_width,3);
      obje_type.Set_property_info(vop_color_borders_mouse_moving,clrLightBlue);
      obje_type.Set_property_info(vop_color_borders_selected,clrYellow);
      obje_type.Set_property_info(vop_is_change_color_borders_on_mouse_move,true);
      obje_type.Set_property_info(vop_is_change_color_borders_on_select,true);
      obje_type.Set_property_info(vop_is_selected,false);
      obje_type.Set_property_info(vop_is_my_event_MOUSE_DOWN_UP_CLICK_LEFT,true);
      color clr=0;
      switch(eNode_type(i1+1))
        {
         case nt_function:
           {
            clr=clrDimGray;
            break;
           }
         case nt_indicator_data:
           {
            clr=clrNavy;
            break;
           }
         case nt_indicator:
           {
            clr=clrMaroon;
            break;
           }
         case nt_if:
           {
            clr=clrBlack;
            break;
           }
         case nt_const:
           {
            clr=clrGreen;
            break;
           }
         case nt_buffer:
           {
            clr=clrBlue;
            break;
           }
         case nt_node_top:
           {
            clr=clrIndigo;
            break;
           }
        }
      obje_type.Set_property_info(vop_color_borders,clr);
      obje_type.Set_property_info(vop_color_back,clr);
      obje_type.Create(_object_types);
      obje_type.Add_event_handler(GetPointer(my_handler));
      obje_type_text=new cV_object_label();
      obje_type_text.Set_property_info(vop_text,StringSubstr(EnumToString(eNode_type(i1+1)),3));
      obje_type_text.Set_property_info(vop_color_back,clrWhite);
      obje_type_text.Set_property_info(vop_size_x,width_type-1);
      obje_type_text.Set_property_info(vop_position_x,-3);
      obje_type_text.Set_property_info(vop_position_y,5-3);
      obje_type_text.Set_property_info(vop_text_anchor,TA_CENTER);
      obje_type_text.Set_property_info(vop_font_size,18);
      obje_type_text.Create(obje_type);
     }
   _object_types.Get_child(0).Set_property(vop_is_selected,true);
//Окно отображения объектов
   cV_object_rectangle *objects_viever=new cV_object_rectangle();
   objects_viever.Set_property_info(vop_position_x,0);
   objects_viever.Set_property_info(vop_position_y,height_type+_object_types.Get_property(vop_position_y).data_long);
   objects_viever.Set_property_info(vop_size_x,width_object);
   objects_viever.Set_property_info(vop_size_y,30*height_object);
   objects_viever.Create(_main_window);
//Контейнер объектов
   int functions_count=cRules::Get_object_count(nt_function);
   _objects=new cV_object_base();
   _objects.Set_property_info(vop_position_x,0);
   _objects.Set_property_info(vop_position_y,0);
   _objects.Set_property_info(vop_size_x,width_object);
   _objects.Set_property_info(vop_size_y,functions_count*height_object);
   _objects.Set_property_info(vop_color_back,clrOlive);
//_objects.Set_property_info(vop_is_position_fixing_parent_x,true);
//_objects.Set_property_info(vop_is_position_fixing_parent_y,true);
   _objects.Create(objects_viever);
//Объекты
   for(int i1=0; i1<functions_count; i1++)
     {
      cV_object_label *object=new cV_object_label();
      object.Set_property_info(vop_size_x,width_object-2);
      object.Set_property_info(vop_position_x,1);
      object.Set_property_info(vop_position_y,i1*height_object);
      object.Set_property_info(vop_color_back,clrWhite);
      object.Set_property_info(vop_text,cRules::Get_object_name(nt_function,i1));
      object.Set_property_info(vop_text_anchor,TA_LEFT);
      object.Set_property_info(vop_font_size,height_object-2);
      object.Create(_objects);
     }
  }

上部のボタンをクリックしたときのイベントを処理します。

void cStrategy_viewer::cMy_handler::On_event(sEvent &event)
  {
   cV_object_base *obj=GetPointer(event.object);
   switch(event.id)
     {
      case CHARTEVENT_CLICK_:
        {
         if(obj.Get_parent()==GetPointer(md._object_types))
           {
            obj.Set_property(vop_is_selected,true);
           }
         break;
        }
     }
  }

複数のボタンがあり、親ウィンドウは1つだけ

ファイル:
 
Реter Konow:

そんなバグがあったんですね。修正しました。イベント自体は問題なく修正されていますが、コード開発で避けられない様々な変更でバグが発生します。

そう、複雑なんです。

デモでの一枚。


 
ただ、このようなビジネスでは、まずイベントやウィンドウの制御を工夫すれば、あとは簡単なのですが、他でやることがたくさんあるのです。
 
ビジュアルエレメントライブラリをゼロから作ることに興味がある人 :)?
 
Aliaksandr Hryshyn:
ただ、この場合、まずイベントとウィンドウコントロールを凝る必要があり、あとは簡単なのですが、やることはたくさんあるのです。

その下地はすでにできているのです。

1: ウィンドウには閉じるボタンと折りたたみボタンが必要です(最低限)。

2: ウィンドウをクリックすると、ウィンドウが重なって再描画されるようにする。

3: マウスでウィンドウが移動するようにします。

4: カーソルが移動したときに、チャート上でウィンドウが「検出」(フォーカスされる)されること(ポイント イベント)。

5.ウィンドウのすべての要素は、ウィンドウの共通の「マップ」上にあり、マウスがホバーされた(イベントがポイントされた)ときに検出される必要があります。

 

最もシンプルな要素。

1.静的で、次元の変わらない、消えないWindow。

2.ボタンです。

3.チェックボックス

4.ラジオボタンです。

5.タブ

6.線、枠、仕切り、長方形。


中程度の複雑さの要素。

1.スライダー

2.プログレスバー

3.入力欄です。

4.スクロールするフィールド。

5.シンプルなリスト項目。


高難易度項目。

1.ドロップダウン・リスト(非常に複雑な要素)。

2.ダイナミック(伸縮自在)なウィンドウ。超複雑。


コントロールの種類は約50種類。それぞれ、対応するエンジン機能でサポートされる、共通かつ独自のプロパティセットを 持つ必要があります。プロパティが100以上でないと、エレメントの働きが著しく制限されます。

単純な形や線であれば、それほど多くのプロパティは必要ありませんが、複雑な要素になればなるほど、その数は多くなります。
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Свойства объектов
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Свойства объектов
  • www.mql5.com
Все объекты, используемые в техническом анализе, имеют привязку на графиках по координатам цены и времени – трендовая линия, каналы, инструменты Фибоначчи и т.д.  Но есть ряд вспомогательных объектов, предназначенных для улучшения интерфейса, которые имеют привязку к видимой всегда части графика (основное окно графика или подокна индикаторов...
 

しまった、テーブルを忘れていた!外はジャングルですからね... ))))

そして、ツリー状のリスト、あらゆる種類のコラプサー...。

 
各インタラクティブ・コントロールは、それ自身のプロパティを持つ制御されたパラメータを持ちます。例えば、ボタンにはbool型(1または0)のパラメータ、入力フィールドには文字列型の パラメータ、スライダーには範囲型のパラメータ...といった具合です。ボタン付き入力フィールドは、current_value, last_value, min, max, step, value_type などのプロパティを持つパラメータを持ちます。各プロパティは、機能によってサポートされています。

各インタラクティブ要素は、異なるイベントで変化する8種類の状態を持つことが理想的です。

例:neutral, neutral_pointed, activated_neutral, activated_pointed, neutral_highlighted, activated_highlighted, neutral_locked, activated_locked.

各状態は、要素のプロパティ値を独自に設計し、特殊な機能によって固定された独自のイベントで発効する。
 
Реter Konow:

しまった、テーブルを忘れていた!外はジャングルですからね... ))))

ツリー状のリストや、いろいろなコラプサーも...。

私の場合、表示ウィンドウ(テーブルの可視領域)、すべてのセルが収まる必要があるフルサイズのウィンドウ、それはメインウィンドウ内でスライドします、行とその中のセルのウィンドウ、さらにスクロール(バーで囲まれたスライダー)、平均よりも複雑ではありません "ジャングル "です。相対位置の制約は、プロパティによって決定される。スライダーのみ、オブジェクトの移動イベントを インターセプトし、すでに「フルサイズウィンドウ」の位置を修正する必要があります。これはすべて仮想ウィンドウで行われます。ビジュアル部分をボルトで固定する必要があり、ビジュアル部分がなければ、ライン用のウィンドウとフルサイズのウィンドウが存在します。そして、編集可能なセルには、入力フィールドを作ります(これはカスタムです)。その他のことは、すべてエンジンが処理します。以上が可能性ですが、ウィンドウが多すぎる場合(大きなリスト、テーブル、数千のウィンドウ)にパフォーマンスを上げるためのアイデアもいくつかあります。