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

 
Aliaksandr Hryshyn:

更多。

用鼠标右键点击窗口区域,出现一个菜单。移动鼠标,用鼠标左键点击。这将导致窗口的移动。

这是有可能的。告诉你,我自己在开发和测试,所以我根本不知道一些bug,直到我在过程中不小心遇到它们。我一个人做所有的事情...

 

这是我的例子,在所附文件中,有三个窗口相互重叠。

创建一个有子窗口的窗口是这样的,只是使用引擎,没有额外的代码。除了处理 点击顶部按钮的事件

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

有几个按钮,只有一个父窗口

附加的文件:
 
Реter Konow:

有这样一个错误。修正了它。事件本身修复得很好,但在代码开发中无法避免的各种变化会出现bug。

是的,这很复杂。

演示中的一张照片。


 
只是在这样的业务中,你首先要做的是解决事件和窗口控制的问题,其余的就比较容易了,尽管其他地方还有很多工作要做。
 
有谁对从头开始制作一个视觉元素库感兴趣吗 :)?
 
Aliaksandr Hryshyn:
只是在这种情况下,首先,我们必须详细说明事件和窗口控制,其余的就比较容易了,但要做的工作就多了。

基础工作已经就绪。

1:窗口应该有关闭和折叠按钮(至少)。

2:点击时,窗口应该在彼此的上面重绘。

3、窗口应随鼠标移动。

4:当光标移动时,图表上的窗口应被 "检测"(被带入焦点)(尖锐 事件)。

5.窗口的所有元素必须在窗口的一个共同 "地图 "上,并在鼠标悬停时被检测到(事件指向)。

 

最简单的元素。

1.一个静态的、尺寸不变的、不可磨灭的窗口。

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:

妈的,我忘了桌子的事。外面是一片丛林... ))))

还有一个树状的列表,以及各种折叠器...

在我的例子中,"丛林 "并不比一般的复杂:一个显示窗口(表格的可见区域),一个全尺寸的窗口,所有的单元格必须适合,它将在主窗口内滑动,行和单元格的窗口,加上滚动(一个由条形图限定的滑动器)。相对定位的约束由属性决定。只有对滑块来说,有必要拦截对象的移动事件,并且已经纠正了"全尺寸窗口 " 的位置。这都是由虚拟窗口完成的,我们需要把视觉部分栓在上面,如果没有视觉部分,就会有线条的窗口和全尺寸的窗口。对于可编辑的单元格,做一个输入字段(这是一个自定义的字段),所有其他的东西将由引擎处理 - 它将为每个单元格获得正确的事件(鼠标事件,重绘,移动).....这些都是可能性,但也有几个想法可以在窗口过多的情况下提高性能(大型列表、表格、几千个窗口)。

原因: